【发布时间】:2012-01-14 18:20:22
【问题描述】:
(我已经编辑了这个问题以避免分心。有一个核心问题需要在任何其他问题变得有意义之前得到澄清。向现在的答案似乎不太相关的任何人道歉。)
让我们设置一个具体的例子:
struct Base {
int i;
};
没有虚方法,也没有继承,一般是一个很笨很简单的对象。因此它是Plain Old Data (POD),它依赖于可预测的布局。特别是:
Base b;
&b == reinterpret_cast<B*>&(b.i);
这是根据Wikipedia(它本身声称引用了C++03标准):
一个指向 POD-struct 对象的指针,使用 reinterpret cast 进行适当转换,指向它的初始成员,反之亦然,这意味着在 POD-struct 的开头没有填充。[8]
现在让我们考虑继承:
struct Derived : public Base {
};
同样,没有虚拟方法,没有虚拟继承,也没有多重继承。因此这也是 POD。
问题:这个事实(Derived 是 C++11 中的 POD)是否允许我们这样说:
Derived d;
&d == reinterpret_cast<D*>&(d.i); // true on g++-4.6
如果这是真的,那么下面的定义是明确的:
Base *b = reinterpret_cast<Base*>(malloc(sizeof(Derived)));
free(b); // It will be freeing the same address, so this is OK
我不是在这里询问new 和delete - 更容易考虑malloc 和free。我只是对像这种简单情况下派生对象布局的规定以及基类的初始非静态成员位于可预测位置的位置感到好奇。
Derived 对象应该等同于:
struct Derived { // no inheritance
Base b; // it just contains it instead
};
事先没有填充?
【问题讨论】:
-
C++11 主要废除了“POD”术语,取而代之的是 standard-layout 和 trivially-copyable(至少所有有趣的要求使用这些更广泛的术语)。修正您的问题以使用正确的术语。
-
@BenVoigt,好主意。今晚有空时,我会尽力解决这个问题。
-
c++11 仍然有 POD,而且他的问题对于所使用的术语仍然有意义。
-
另外,从“如果这是真的”开始的所有内容都应该是一个新问题,它与标题完全无关。
标签: c++ c++11 language-lawyer