如果我有一个带有多个base的派生类,每个base的每个this指针都不同于派生对象的this指针,除了一个。给定继承层次结构中的两种类型,我想在编译时检测它们是否共享相同的this指针。这样的事情应该有效,但不会:
BOOST_STATIC_ASSERT(static_cast<Base1*>((Derived *)0xDEADBEEF) == (Derived*)0xDEADBEEF);
因为它需要是一个“整型常量表达式”,并且根据标准只允许整数强制转换(这是愚蠢的,因为如果没有使用虚拟继承,它们只需要编译时信息)。尝试将结果作为整数模板参数传递时会出现同样的问题。
我能做的最好的事情是在启动时检查,但我需要在编译期间获取信息(以获得一些深层模板hackery工作)。
答案 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)
使用
怎么样?BOOST_STATIC_ASSERT(boost::is_convertible<Derived*,Base*>::value)
如以下位置所述......
http://www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html
答案 5 :(得分:0)
我没有意识到编译器会在运行时插入此检查,但您的基本假设并不完全正确。可能不是您关心的方式:如果您碰巧使用sizeof(base class)==0
从多个基类继承,编译器可以使用空基类优化。这将导致(base class *)(derived *)1==at least one other base class
。
就像我说的,这可能不是你真正需要关心的事情。