C ++,静态检测具有不同地址的基类?

时间:2009-07-15 14:09:42

标签: c++ memory templates multiple-inheritance static-cast

如果我有一个带有多个base的派生类,每个base的每个this指针都不同于派生对象的this指针,除了一个。给定继承层次结构中的两种类型,我想在编译时检测它们是否共享相同的this指针。这样的事情应该有效,但不会:

BOOST_STATIC_ASSERT(static_cast<Base1*>((Derived *)0xDEADBEEF) == (Derived*)0xDEADBEEF);

因为它需要是一个“整型常量表达式”,并且根据标准只允许整数强制转换(这是愚蠢的,因为如果没有使用虚拟继承,它们只需要编译时信息)。尝试将结果作为整数模板参数传递时会出现同样的问题。

我能做的最好的事情是在启动时检查,但我需要在编译期间获取信息(以获得一些深层模板hackery工作)。

6 个答案:

答案 0 :(得分:2)

我不知道如何检查你想要什么,但请注意,在存在空基类的情况下,你的假设是错误的。它们中的任意数量都可以与对象的开头共享相同的偏移量,只要它们的类型不同。

答案 1 :(得分:2)

我正在努力解决这个完全相同的问题。如果您知道基类的布局开头的成员变量,我有一个实现。例如。如果成员变量“x”存在于每个类的开头,则以下代码将用于从派生类布局中生成特定基类布局的字节偏移量:offsetof(derived,base2 :: x)。

在以下情况下:
struct base1 { char x[16]; };
struct base2 { int x; };
struct derived : public base1, public base2 { int x; };
static const int my_constant = offsetof(derived, base2::x);

编译器会在我的架构(x86_64)上为my_constant正确分配“16”。

当您不知道基类布局开头的成员变量时,难以获得“16”。

答案 2 :(得分:1)

我甚至不确定这个偏移是一个常数。你有没有提出规范的措辞吗?

我同意在没有虚拟继承的情况下,非const偏移很难实现,而且无法启动。这不仅仅是重点。

答案 3 :(得分:1)

类没有this指针 - 类的实例,并且对于每个实例它们都是不同的,无论它们是如何派生的。

答案 4 :(得分:1)

答案 5 :(得分:0)

我没有意识到编译器会在运行时插入此检查,但您的基本假设并不完全正确。可能不是您关心的方式:如果您碰巧使用sizeof(base class)==0从多个基类继承,编译器可以使用空基类优化。这将导致(base class *)(derived *)1==at least one other base class

就像我说的,这可能不是你真正需要关心的事情。