2012-07-02 53 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