标准布局 c++

Standard Layout c++

本文关键字:c++ 布局 标准      更新时间:2023-10-16

我正在浏览有关C++ POD,琐碎和标准布局类的精彩文章我对标准布局没有明确了解的一个属性如下:-

 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   
};

这是对上面那个的更正。

原因是标准布局类型有效地强制要求"空基类优化",其中没有数据成员的基类不占用空间,并且与派生类的第一个数据成员(如果有)具有相同的地址。

但是,当基类与第一个数据成员具有相同的类型时尝试执行此操作会违反C++内存模型,该模型要求相同类型的不同对象必须具有不同的地址。

摘自ISO/IEC 14882:2011 1.8 [intro.object]/6:

如果两个对象是另一个对象的子对象,

或者至少有一个对象是大小为零的基类子对象并且它们属于不同的类型,则不是位字段的两个对象可能具有相同的地址;否则,它们应具有不同的地址

有效地强制要求空基类,9.2 [class.mem]/20:

指向标准布局结构对象的指针,使用 reinterpret_cast 进行适当转换,指向其 初始成员(或者,如果该成员是位字段,则到它所在的单元),反之亦然。

如果没有这个限制,以下类型(Type1Type2)不可能与布局兼容(尽管它们本来是标准布局类)。

struct S1 {};
struct S2 {};
struct Type1 : S1 {
    S1 s;
    int k;
};
struct Type2 : S1 {
    S2 s;
    int m;
};