18

C++ POD、Trivial、Standard Layout クラスに関するすばらしい記事を読んで いましたが、標準レイアウトについて明確に理解していないプロパティの 1 つは次のとおりです。

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

しかし、パフォーマンスとプロパティの観点から、上記の構造体はどのように異なるのですか

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

これは、この上のものの修正です。

4

1 に答える 1

17

その理由は、標準のレイアウト タイプでは、データ メンバーを持たない基本クラスがスペースを占有せず、派生クラスの最初のデータ メンバー (存在する場合) と同じアドレスを持つ「空の基本クラスの最適化」を効果的に義務付けているためです。

ただし、基本クラスが最初のデータ メンバーと同じ型を持つ場合にこれを実行しようとすると、同じ型の個別のオブジェクトには個別のアドレスが必要であるという C++ メモリ モデルに違反します。

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

ビット フィールドではない 2 つのオブジェクトは、一方が他方のサブオブジェクトである場合、または少なくとも 1 つがサイズ 0 の基底クラス サブオブジェクトであり、それらが異なる型である場合、同じアドレスを持つ可能性があります。それ以外の場合、それらは別個のアドレスを持つものとします

空の基本クラス、9.2 [class.mem] /20 を効果的に義務付けます。

を使用して適切に変換された標準レイアウト構造体オブジェクトへのポインターは、reinterpret_castその最初のメンバー (または、そのメンバーがビットフィールドの場合は、それが存在するユニット) を指し、その逆も同様です。

この制限なしでは、次の型 (Type1およびType2) をレイアウト互換にすることはできません (ただし、それ以外の場合は標準レイアウト クラスになります)。

struct S1 {};
struct S2 {};

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

struct Type2 : S1 {
    S2 s;
    int m;
};
于 2012-07-02T20:19:35.677 に答える