2

如果我有一个具有多个基的派生类,则每个基的每个 this 指针都将不同于派生对象的 this 指针,除了一个。给定继承层次结构中的两种类型,我想在编译时检测它们是否共享相同的 this 指针。像这样的东西应该可以工作,但不能:

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

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

我能做的最好的事情是在启动时检查,但我需要在编译期间的信息(让一些深入的模板黑客工作)。

4

6 回答 6

2

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

于 2009-07-15T14:19:59.013 回答
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) 上正确地将“16”分配给 my_constant。

当您不知道基类布局开始处的成员变量是什么时,困难在于获得“16”。

于 2010-09-02T02:25:27.607 回答
1

怎么用

BOOST_STATIC_ASSERT(boost::is_convertible<Derived*,Base*>::value)

如以下位置所述...

http://www.boost.org/doc/libs/1_39_0/doc/html/boost_staticassert.html

http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetraits/reference/is_convertible.html

于 2009-07-15T14:48:52.557 回答
1

我什至不确定这个偏移量是否是一个常数。您是否有其他建议的规范性措辞?

我同意在没有虚拟继承的情况下非常难以实现非常量偏移,并且启动毫无意义。这不是重点。

于 2009-07-15T14:27:25.757 回答
1

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

于 2009-07-15T14:35:37.490 回答
0

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

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

于 2009-07-15T16:31:10.470 回答