【发布时间】:2012-06-18 08:50:37
【问题描述】:
我知道多重继承的内存布局没有定义,所以我不应该依赖它。但是,我可以在特殊情况下依赖它吗?也就是说,一个类只有一个“真正的”超类。所有其他都是“空类”,即既没有字段也没有虚拟方法的类(即它们只有非虚拟方法)。在这种情况下,这些额外的类不应向类的内存布局添加任何内容。 (更简洁地说,在 C++11 的措辞中,该类具有 standard-layout)
我可以推断所有超类都没有偏移量吗?例如:
#include <iostream>
class X{
int a;
int b;
};
class I{};
class J{};
class Y : public I, public X, public J{};
int main(){
Y* y = new Y();
X* x = y;
I* i = y;
J* j = y;
std::cout << sizeof(Y) << std::endl
<< y << std::endl
<< x << std::endl
<< i << std::endl
<< j << std::endl;
}
这里,Y 是类,X 是唯一真正的基类。程序的输出(在linux上用g++4.6编译时)如下:
8
0x233f010
0x233f010
0x233f010
0x233f010
正如我的结论,没有指针调整。但是这个实现是特定的还是我可以依赖它。即,如果我收到I 类型的对象(并且我知道只存在这些类),我可以使用reinterpret_cast 将其转换为X 吗?
我希望我可以依赖它,因为规范说对象的大小必须至少是一个字节。因此,编译器无法选择其他布局。如果它将I 和J 布局在X 的成员后面,那么它们的大小将为零(因为它们没有成员)。因此,唯一合理的选择是对齐所有超类而不偏移。
如果我在这里使用从I 到X 的reinterpret_cast,我是正确的还是我在玩火?
【问题讨论】:
-
继承的内存布局,单个或多个,空基与否,未定义。
-
我会说你是在玩火,因为你试图制造一个非常奇怪的结构,这肯定会给将来必须理解它的任何人带来痛苦和痛苦,即使它升级编译器时不会中断!
-
幸运的是,您的陈述在 C++11 中不再正确,请参阅答案 :)
-
@n.m.它是实现定义。实现需要记录它,所以它是定义的,只是不在标准中。
标签: c++ multiple-inheritance memory-alignment