C ++のクラスのサイズがデータメンバーのパブリック/プライベートステータスに依存するのはなぜですか?


23

私が知っていることから、C ++のクラスのサイズは以下の要因に依存します-

  1. すべての非静的データメンバーのサイズ。
  2. データメンバーの順序。
  3. バイトパディングが有効かどうか。
  4. 直接の基本クラスのサイズ。
  5. 仮想機能の存在。
  6. 継承のモード(仮想継承)。

今私は以下のように2つのクラスを作成しました-

class A{
    int a;
    short s;
    int b;
    char d;
};// kept a char at last on purpose to leave a "hole"

class B : public A{
    char c;  
};

AとBIのサイズを確認する

  • Aのサイズ:16
  • Bのサイズ:16

私の仮定は、クラスBのchar cがクラスAに残された「穴」に収容されることです。

しかし、私を混乱させているのは、メンバーを公開する以下のシナリオです

class A{
    public:
    int a;
    short d;
    int b;
    char s;
};

class B : public A{
    public:
    char c;
};

今サイズになります

  • Aのサイズ:16
  • Bのサイズ:20

この違いの理由が理解できないようです。


1
C ++のクラスのサイズがデータメンバーのパブリック/プライベートステータスに依存するのはなぜですか?-そうではありません。これらはコンパイラに依存する実装の詳細です。
PaulMcKenzie

1
では、どのコンパイラを使用していますか?
Romen、

2
@PaulMcKenzie実際にそうです。標準では、同じアクセス権を持つメンバーがグループ化されることを義務付けているため、変更すると、コンパイラーのパディング戦略が変更されます。
NathanOliver

@ NathanOliver-ReinstateMonica、私はそれを知りませんでした。たまたま、関連するセクションへの参照がありますか?
R Sahu

@RSahu私の答えを今タイトに入れるためにそれを調べます。
NathanOliver

回答:


8

Itanium ABI は、PODのC ++ 03定義を使用して、「レイアウトのためのPOD」であるクラスを定義します。プライベートデータメンバーがあると、クラスが集合体であると見なされなくなるため、C ++ 03ではPODになります。

POD-構造体は、全く非静的データ型非POD-構造体、非POD-組合(またはそのようなタイプのアレイ)のメンバーまたは参照を持たない集約クラスであり、かつユーザ定義のコピー代入演算子を持っていないと無ユーザー定義のデストラクタ。

PODクラスであること テールパディングの再利用が無効になります

これらのタイプのdsize、nvsize、およびnvalignは、通常のサイズと配置になるように定義されています。これらのプロパティは、基本クラスとして使用される空でないクラスタイプにのみ関係します。PODのテールパディングは無視します。標準の初期のバージョンでは、それを他の用途に使用することができなかったため、タイプのコピーを高速化できる場合があるためです。

したがって、最初の例でAははレイアウト目的のPOD ではなく、そのテールパディングはに使用できますB::cが、2番目の例ではPODであり、そのテールパディングは再利用できません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.