C++クラスのメモリ割当て


今日の面接でクラスのメモリの問題を聞かれましたが、覚えていません.C++を使ってこんなに年を取ったのは、本当にすべきではない.
そこでインターネットでいくつかの資料を調べて、実験をして、以下のように整理しました.
使用するテスト環境は64ビットmac air、コンパイラはXCode
1.最も簡単
class Test { public: int a ; };
printf("size=%d
",sizeof(Test));

これはみんなが推測できると信じています.答えは4.これは説明しません.
特筆すべきは、
    Test t;

    printf("%d,%d",&t,&(t.a));

t,t.aの住所と同じです
 
 
2.メンバー関数の追加
class Test { public: int a ; int tt(){return 0;} };

これはちょっと難しいかもしれません.4だと推測する人もいれば、8だと推測する人もいれば、他の人もいます.
これは、メンバー関数がクラス(またはオブジェクト)に属していないため、すべてのメンバー関数やグローバル関数などがコードセグメントにあるため、メンバー関数を呼び出すと暗黙的にthisが渡されます.このthisの役割は、オブジェクト内のすべてのメンバー変数を渡すことです.
この点については、「Luaプログラミング」の「対象向け」の章を読んだことのある方が、より深く理解できるかもしれません.
 
3.static  
class Test

{

public:

    int a ;

    static int b ;



    int tt(){return 0;}

};

結果は依然として4で、static変数はメモリを占有しませんか??
いいえ、static変数は静的領域に格納され、通常のメンバー変数とは1つの領域には格納されませんので、依然として4です.
 
4.virtualを追加
 
class Test

{

public:

    int a ;

    virtual int tt(){return 0;}

};

virtualを1つ追加すると、1つの虚関数テーブルポインタが追加されます(複数の虚関数があっても、1つの虚関数テーブルしかありません).
興味深い問題は、1つのポインタが何バイトを占めているのか、4バイトなのかということです.
いいえ、実は機械の文字長と関係があります.32ビットの機械では4バイトで、64ビットの機械では8バイトです.
だから私のコンパイル環境では、この答えは12です.
 
5.相続の場合
継承する場合、子クラスのバイト数は親クラスに子クラスを加える.
ただし、サブクラスには虚関数テーブルポインタが1つしかなく、親虚関数と子虚関数を指すテーブルであることに注意してください.