C++の各種類の大きさ

4475 ワード

注意:このテストインスタンスで使用するコンパイラのバージョンはclang-703.0.29で、システムintの長さは4バイト、ポインタの長さは8バイトです.
1.空のクラス
class A {};

空のsizeofの結果は1で、どうして0ではありませんか?C++規格では、2つの異なるインスタンスのメモリアドレスが異なる必要があることが規定されているため(ここをスタンプ)、このバイトで異なるメモリアドレスを占有し、空のクラスの2つのインスタンスを互いに区別することができる.多くのコンパイラでは、空ベースクラスの最適化(Empty Base Class Optimization、EBCO)がサポートされています.つまり、空ベースクラスから派生したクラスは1バイトも増加しません.
class B : A {
  int a;
};

sizeof(B)の結果は5または8ではなく4であった.
2.静的データメンバーを持つクラス
class C {
  int a;
  static int b;
};

sizeof(C)の結果は4であり,静的データメンバーはクラスオブジェクトの外に格納される.
3.非虚関数メンバーを持つクラス
class D {
  public:
    void func1() {}
    static void func2() {}
};

sizeof(D)の結果は1であり,通常のメンバ関数でも静的メンバ関数でもクラスオブジェクトの外に格納される.
4.虚関数メンバーを持つクラス
class E {
  public:
    virtual void func() {}
};

sizeof(E)の結果は8で、虚関数メンバーを持つクラスオブジェクトには、そのクラスを指すvirtual tableのポインタが含まれます.
5.整列規則
class F {
  char a;
  int  b;
};

sizeof(F)の結果は5ではなく8であり,Fの最大整列値は4(int)であるため,aとbの間に3バイトが加算される.
6.一般派生クラス
class G : public C {
  int a;
};

sizeof(G)の結果は8であり,派生クラスはベースクラスの非静的データメンバー(Cのa)のコピーを格納する.
7.ベースクラス虚関数付き派生クラス
class H : public E {};

sizeof(H)の結果は8であり,ベースクラスには虚関数があるため,派生クラスにも派生クラスへのvirtual tableへのポインタを保存する必要がある.
8.多重継承派生クラス
class I : public B, public C {};

sizeof(I)の結果は、8、BおよびCの非静的データメンバー長、およびvirtual tableへのポインタが必要かどうかの合計である.
9.多重継承での整列規則
class J : public B, public F {
  char a;
};

sizeof(J)の結果は16,B,F,Jクラスにはintの2つのcharが2つあり,整列後4*4の結果は16であった.
10.ダミー継承派生クラス
class K : virtual public A {};

class L : virtual public B {};

sizeof(K)の結果は8であり,派生クラスには虚継承ベースクラスの一意のインスタンスを指すポインタが格納される.sizeof(L)の結果は16であり,整列規則intが補完されるためである.虚継承と虚関数は2つの全く異なる概念であり,それらの間には直接的な関連はないことに注意してください.
class M : virtual public A {};

class N : public K, public M {};

sizeof(N)の結果は16であり,KクラスとMクラスの虚継承ポインタは同じベースクラスインスタンスを指すが,それらは異なるポインタであり,Nクラスにはこれら2つのポインタを同時に格納する必要がある.
転載先:https://www.cnblogs.com/openxxs/p/5400754.html