c++におけるクラスのサイズの問題

3719 ワード

私はかつて《C言語の中で構造体の大きさについての問題》の中で構造体の大きさの問題を詳しく述べたことがあって、今晩の筆記試験は1つの虚関数類の大きさの問題に出会って、少しぼんやりしていて、先日ちょうど良いのはまた虚が継承する時類の大きさの問題を見て、ここで一緒に整理します.
クラスは構造体のアップグレードと見なすことができるので、クラスのメモリレイアウトと構造体は似ていますが、いくつかの違いがあります.以下では、これらの違いについて説明します.
継承
class A
{
    int ma;
};
class B:A
{
    int mb;
};
B b;

bのメモリ構造はmaであり,mbは順次配列される.すなわち,通常は関係を継承し,派生クラスオブジェクトのメモリレイアウトは先ベースクラスのメンバー,後にクラス独自のメンバーを派生する.具体的なルールはstructにstructメンバーがいるルールと同じです.
かそうかんすう
虚関数を持つクラスには、すべてのデータ・メンバーの前に配置される虚関数テーブルを指すポインタがあります.つまり、このポインタはオブジェクト・メモリ・ブロックの開始位置にあります.
class A
{
    int ma;
public:
    A():ma(1) {}
    virtual ~A() {}
};
class B:A
{
    int mb;
public:
    B():mb(2) {}
};
B b;

bのメモリレイアウトは:00 31 42 00//虚関数テーブルへのポインタ01 00 00 00 00 02 00
ダミー継承
class A
{
    int a;
public:
    A():a(1){}
};

class B:virtual A
{
    int b;
public:
    B():b(2){}
};

class C:virtual A
{
    int c;
public:
    C():c(3){}
};

class D:B,C
{
    int d;
public:
    D():d(4){}
};

void main()
{
    A a;
    B b;
    C c;
    D d;
}

結果:
a:01 00 00 00 00 b:1 C 00 47 00//ポインタ02 00 00 00 00 00 01 00 c:28 00 47 00//ポインタ03 00 00 00 00 00 00 00 00 00 00 d:40 00 47 00 02 00 00 34 00 47 00 03 00 00 00 00 00 00 00 00 00 00 00
bとcの開始アドレスにはポインタがあり、オフセット量に関する配列を指し、虚継承を実現するために使用され、このポインタについては、少し複雑で、言わない.もう一つ重要なのは、b、c、d、class Aのデータが末尾に置かれていることです!
せいてきへんすう
staticメンバーは静的領域に格納され、クラスのサイズを占有しません.このようなクラスのsizeofは、そのオブジェクトのsizeofと同じです.例:
class Test {
    static int i;
};
int Test::i = 1;
static int i;は宣言int Test::i = 1;に相当し、iを定義するのはグローバル変数に相当するが、役割ドメインはTestに限られる.
2つの例
1.
class A
{
    double a;
};

class B:virtual public A
{
    int b;
};

Sizeof(A)=8,sizeof(B)=16はAのデータが後であり,Bのデータが前であることを証明する.
2.
class A
{
    double a;
public:
    virtual ~A(){}
};

class B:public A
{
    int b;
};

Sizeof(A)=16,sizeof(B)=24はAのデータが前であり,Bのデータが後であることを証明する.
拡張読解:C++クラスのサイズ-sizeof()http://blog.csdn.net/pizi0475/article/details/6292556