2012-07-02 54 views
15

我所经历的大文章上C++ POD, Trivial and Standard Layout classes 一个特性我还没有清楚地理解有关标准布局如下: -标准布局的C++

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

但性能代价和属性明智如何在上述结构的任何比

不同

这是上面这个的修正。

+0

相关[post](http://stackoverflow.com/q/7160901/183120)。 – legends2k

回答

15

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

但是,当基类具有与第一个数据成员相同的类型时尝试执行此操作违反了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; 
}; 
+3

这正是§9/ 7中这条规则的脚注所说的:“[此规则]确保两个具有相同类类型并且属于同一最大派生对象的子对象不会分配在相同的地址处” –

+0

根据C++ 14,Type2是*标准布局*类,并且依照N4606和[C++ 1z](http://eel.is/c+)继续成为*标准布局*类。 + draft/class#7),因为'S1'与'S2'不是同一个类型。 – Belloc