2012-07-02 10 views
15

Ich war auf C++ POD, Trivial and Standard Layout classes Eine Eigenschaft durch große Artikel gehen habe ich nicht klar über Standard-Layout verstanden ist die folgende: -Standardlayout C++

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

sind also folgende nicht ein Standard-Layout, wie es ist das erste Element gleich der Basisklasse

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

Aber leistungsmäßig und Eigentum weisen, wie die oben Struktur anders als

ist

Das ist die Korrektur des einen darüber.

+0

Ähnliche [post] (http://stackoverflow.com/q/7160901/183120). – legends2k

Antwort

15

Der Grund ist, dass Standard-Layout-Typen effektiv die "leere Basisklassenoptimierung" vorschreiben, wo Basisklassen ohne Datenelemente keinen Platz einnehmen und die gleiche Adresse wie das erste Datenelement (falls vorhanden) der abgeleiteten Klasse haben.

Wenn jedoch versucht wird, dies zu tun, wenn die Basisklasse den gleichen Typ wie das erste Datenelement aufweist, verletzt dies das C++ - Speichermodell, das unterschiedliche Objekte desselben Typs erfordert.

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

Zwei Objekte, die nicht Bit-Felder sind, können die gleiche Adresse haben, wenn man ein Subobjekt des anderen ist, oder wenn mindestens eins ist ein Unterobjekt der Basisklasse mit der Größe null und sie sind von unterschiedlicher Art; Andernfalls werden sie unterschiedliche Adressen

effektiv die leere Basisklasse Mandatierung haben, 9.2 [class.mem]/20:

Ein Zeiger auf ein Objekt Standard-Layout-Struktur, in geeigneter Weise umgewandelt, um eine Verwendung reinterpret_cast , zeigt auf seinen ursprünglichen Member (oder wenn dieses Mitglied ein Bit-Feld ist, dann auf die Einheit, in der es sich befindet) und umgekehrt.

Es wäre für die folgenden Arten (Type1 und Type2) zu sein Layout-kompatibel unmöglich sein, ohne diese Einschränkung (obwohl sie ansonsten Standard-Layout-Klassen sein würden).

struct S1 {}; 
struct S2 {}; 

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

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

Genau dies besagt auch die Fußnote für diese Regel in §9/7: "[Diese Regel] stellt sicher, dass zwei Unterobjekte, die denselben Klassentyp haben und zum selben am meisten abgeleiteten Objekt gehören, nicht an der gleichen Adresse zugeordnet werden" –

+0

'Type2' war eine * Standard-Layout * -Klasse nach C++ 14 und weiterhin eine * Standard-Layout * -Klasse nach N4606 und [C++ 1z] (http://eel.is/c+ + Entwurf/Klasse # 7), da 'S1' nicht der gleiche Typ wie' S2' ist. – Belloc