C++クラスメモリ分布虚関数単継承マルチ継承


C++クラスメモリ分布虚関数単継承多継承重点内容一、まず継承がない場合のクラスメモリ分布を見る:1.1簡単なクラスを定義し、虚関数がない.コードは次のとおりです.
#include<iostream>
using namespace std;
class Base
{
public:
    int Base_1;
    int Base_2;
public:
    void func1();
};
int main(){
    Base obj_base;
    return 0;
}

コンパイルして得られたメモリ分布図は以下の通りである:ここから一般クラスのメモリ配置方式が見られ、メンバー変数は宣言の順序に従って配列され、クラス内オフセットは0から始まり、一般メンバー関数はメモリ空間を占めない.ここではcharなどのメンバー変数のバイト整列方式などの問題は考慮されていない.1.2虚関数を含む簡単なクラスを定義します.#include<iostream>
using namespace std;
class Base
{
public:
int Base_1;
int Base_2;
public:
void func1();
virtual void func2(){};
virtual void func3(){};
};
int main(){
Base obj_base;
return 0;
}
コンパイルにより得られたメモリ分布図は、図から分かるように、このメモリ構造図はクラスのメモリ分布、以下は虚関数テーブルの2つの部分に分かれている.ここでのコンパイル環境VS 2013.結果から分かるように、コンパイラは虚表ポインタ{vfptr}をクラスメモリの先頭に置き、図からそのオフセット量が0であることがわかり、次にクラスの他のメンバー変数を配置し、図から分かるように、Base_1とBase_2のオフセット量はそれぞれ4,8であった.次のセクションはクラスの虚関数テーブルです.で&Base_metaの後ろの0は,この虚関数テーブルに対応する虚ポインタ{vfptr}のクラスメモリにおける分布を示す.次に、クラスの虚関数をリストします.虚関数の左側には虚関数の番号が表示されます.
1.3単一の非虚継承.
#include<iostream>
using namespace std;
class Base
{
public:
    int Base_1;
    int Base_2;
public:
    void func1();
    virtual void func2(){};
    virtual void func3(){};
};
class D :public Base{
public:
    int d_1;
public:
    virtual void func2(){};
};
int main()
{
    return 0;
}

実行結果:
解析:派生クラスは、虚表ポインタ{vfptr}や他の変数を含むベースクラスのすべてを継承します.親を継承するものをクラスメモリの先頭に置くと、{vfptr}のアドレスが0にシフトし、派生クラスも独自の虚関数テーブルを維持します.まとめ:非虚継承の下で:(1)派生クラスは、虚ベースポインタを含むベースクラスのすべてを継承します.(2)派生クラスとベースクラスは,それぞれ同じテーブルではなく異なる虚関数テーブルを維持する.以上の結果から,ベースクラスの虚表はBase::$vftable,派生クラスの虚表はD::vftableであった.しかし、彼らの虚表に対応する虚ポインタは同じです.
1.4単一虚継承.コード:
#include<iostream>
using namespace std;
class Base
{
public:
    int Base_1;
    int Base_2;
public:
    void func1();
    virtual void func2(){};
    virtual void func3(){};
};
class D :virtual public Base{
public:
    int d_1;
public:
    virtual void func2(){};
};
int main()
{
    return 0;
}

実行結果:
派生クラスは、虚表ポインタ{vfptr}や他の変数を含むベースクラスのすべてを継承します.しかし、親を継承するものをクラスメモリの先頭に置くかどうか.クラスメモリに配置を開始したのは自分の虚ポインタ{vbptr}であり,次に自分のメンバー変数であり,最後にベースクラスから派生したデータを配置する.このとき,派生クラスには2つのダミーポインタがあり,1つは自分のダミーポインタであり,もう1つはベースクラスから派生したダミーポインタであり,対応する2つのダミーテーブルがある.各ダミーテーブルの下の数字は、クラスメモリ内のオフセット量を表します.まとめ:虚継承の下:(1)派生クラスは、虚ベースポインタを含むベースクラスのすべてを継承します.ただし、クラスメモリのアドレスオフセット0に置くかどうか.派生クラスはダミーポインタとして生成され、クラスメモリアドレスのオフセット量が0になります.(2)派生クラスには2つの虚ポインタがあり,2つの虚関数テーブルに対応する.
特に感謝します.http://www.cnblogs.com/jerry19880126/p/3616999.html