2012-07-02 24 views
15

yo estaba pasando por grandes artículos en C++ POD, Trivial and Standard Layout classes Una propiedad que no he entendido con claridad acerca de la disposición normalizada es la siguiente: -diseño estándar de C++

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

Así que el siguiente no habrá un modelo general, ya que tiene el primer miembro misma que la clase base

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

Pero en cuanto al rendimiento y la propiedad en cuanto a cómo es la estructura por encima de cualquier diferente que

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

que es la corrección del que está sobre esto.

+0

Relacionados [publicar] (http://stackoverflow.com/q/7160901/183120). – legends2k

Respuesta

15

La razón es que los tipos de disposición estándar efectivamente imponen la "optimización de clase base vacía" donde las clases base sin miembros de datos ocupan espacio y tienen la misma dirección que el primer miembro de datos (si existe) de la clase derivada.

Sin embargo, intentar hacer esto cuando la clase base tiene el mismo tipo que el primer miembro de datos viola el modelo de memoria C++ que requiere que distintos objetos del mismo tipo tengan direcciones distintas.

A partir de ISO/IEC 14882: 2011 1.8 [intro.object]/6:

Dos objetos que no son campos de bits pueden tener la misma dirección si uno es un subobjeto de la otra, o si al menos uno es un subobjeto de clase base de tamaño cero y son de diferentes tipos; de lo contrario, deberán tener direcciones distintas

que obligan efectivamente la clase base vacía, 9,2 [class.mem]/20:

Un puntero a un objeto struct estándar-layout, adecuadamente convertidos usando un reinterpret_cast , apunta a su miembro inicial (o si ese miembro es un campo de bits, luego a la unidad en la que reside) y viceversa.

sería imposible para los siguientes tipos (Type1 y Type2) para que sea compatible diseño-(a pesar de que de otro modo serían clases de diseño de páginas estándar) sin esta restricción.

struct S1 {}; 
struct S2 {}; 

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

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

Esto es exactamente lo que dice la nota al pie de esta regla en §9/7: "[Esta regla] asegura que dos subobjetos que tienen el mismo tipo de clase y pertenecen al mismo objeto más derivado no están asignados a la misma dirección" –

+0

'Type2' era una clase * layout-standard * según C++ 14 y sigue siendo una clase * layout-standard * según N4606 y [C++ 1z] (http://eel.is/c+ + borrador/clase # 7), ya que 'S1' no es del mismo tipo que' S2'. – Belloc