我正在阅读有关C++ POD, Trivial and Standard Layout classes的精彩文章 我对标准布局没有清楚了解的一个属性如下: -
A standard layout has no base classes of the same type as the first
non-static data member
因此,以下将不是标准布局,因为它具有与基类相同的第一个成员
struct NonStandardLayout3 : StandardLayout1 {
StandardLayout1 x; // first member cannot be of the same type as base
};
但是在性能方面和属性方面,上述结构与
有什么不同struct StandardLayout5 : StandardLayout1 {
int x;
StandardLayout1 y; // can have members of base type if they're not the first
};
这是对此之上的修正。
答案 0 :(得分:15)
原因是标准布局类型有效地强制要求“空基类优化”,其中没有数据成员的基类不占用空间,并且具有与派生类的第一个数据成员(如果有)相同的地址。 / p>
但是,当基类与第一个数据成员具有相同类型时尝试执行此操作会违反C ++内存模型,该模型要求相同类型的不同对象必须具有不同的地址。
来自ISO / IEC 14882:2011 1.8 [intro.object] / 6:
如果一个是另一个的子对象,或者如果至少有一个是零大小的基类子对象并且它们的类型不同,那么两个不是位字段的对象可以具有相同的地址;否则,他们应有不同的地址
有效地强制要求空基类,9.2 [class.mem] / 20:
指向标准布局结构对象的指针(适当地使用
reinterpret_cast
转换)指向它 初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然。
以下类型(Type1
和Type2
)不可能在没有此限制的情况下与布局兼容(尽管它们可能是标准布局类)。
struct S1 {};
struct S2 {};
struct Type1 : S1 {
S1 s;
int k;
};
struct Type2 : S1 {
S2 s;
int m;
};