2012-07-02 29 views
15

ja jechałem przez wielkich artykułów na C++ POD, Trivial and Standard Layout classes jedną właściwość Nie zrozumiałe o standardowym układzie jest następująca: -standardowym układzie C++

A standard layout has no base classes of the same type as the first 
    non-static data member 

Więc dodaje nie będzie layout Standard, jak to ma pierwszy człon samo jak klasy podstawowej

struct NonStandardLayout3 : StandardLayout1 { 
    StandardLayout1 x; // first member cannot be of the same type as base 
}; 

Ale wydajność mądry i mienia mądry jak jest powyżej struct inaczej niż

struct StandardLayout5 : StandardLayout1 { 
    int x; 
    StandardLayout1 y; // can have members of base type if they're not the first 
}; 

, która jest korektą powyższej.

+0

Powiązane [post] (http://stackoverflow.com/q/7160901/183120). – legends2k

Odpowiedz

15

Powodem jest to, że standardowe typy layoutów skutecznie wymagają "pustej optymalizacji klasy bazowej", w której klasy podstawowe bez elementów danych nie zajmują miejsca i mają ten sam adres co pierwszy element danych (jeśli istnieje) klasy pochodnej.

Jednak próba wykonania tej czynności, gdy klasa bazowa ma ten sam typ co pierwszy element danych, narusza model pamięci C++, który wymaga, aby różne obiekty tego samego typu miały odrębne adresy.

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

Dwa obiekty, które nie są bit-pola mogą mieć ten sam adres, jeśli ktoś jest podobiekt z drugiej strony, czy co najmniej jeden jest podobieństwem klasy bazowej o zerowym rozmiarze i są one różnych typów; poza tym mają one różne adresy

skutecznie upoważnień pustą podstawową klasę 9,2 [class.mem]/20:

Wskaźnik do struct obiektu standardowego układu, odpowiednio przekształcone za pomocą reinterpret_cast , wskazuje na swój początkowy element członkowski (lub jeśli ten element jest polem bitowym, a następnie do jednostki, w której się znajduje) i na odwrót.

To byłoby niemożliwe dla następujących typów (Type1 i Type2) być zgodny układ (chociaż miałyby one być zajęcia standardowego układu) bez tego ograniczenia.

struct S1 {}; 
struct S2 {}; 

struct Type1 : S1 { 
    S1 s; 
    int k; 
}; 

struct Type2 : S1 { 
    S2 s; 
    int m; 
}; 
+3

To jest dokładnie to samo, co przypis przypisany do tej reguły w §9/7: "[Ta reguła] zapewnia, że ​​dwa podobiekty, które mają ten sam typ klasy i które należą do tego samego najbardziej wyprowadzonego obiektu, nie są przydzielane pod tym samym adresem" –

+0

'Type2' był * standardowym układem * klasy według C++ 14 i nadal jest klasą * standard-layout * według N4606 i [C++ 1z] (http://eel.is/c+ + szkic/klasa # 7), ponieważ 'S1' nie jest tym samym typem co' S2'. – Belloc