C++クラスのメモリ割当て
3324 ワード
今日の面接でクラスのメモリの問題を聞かれましたが、覚えていません.C++を使ってこんなに年を取ったのは、本当にすべきではない.
そこでインターネットでいくつかの資料を調べて、実験をして、以下のように整理しました.
使用するテスト環境は64ビットmac air、コンパイラはXCode
1.最も簡単
これはみんなが推測できると信じています.答えは4.これは説明しません.
特筆すべきは、
t,t.aの住所と同じです
2.メンバー関数の追加
これはちょっと難しいかもしれません.4だと推測する人もいれば、8だと推測する人もいれば、他の人もいます.
これは、メンバー関数がクラス(またはオブジェクト)に属していないため、すべてのメンバー関数やグローバル関数などがコードセグメントにあるため、メンバー関数を呼び出すと暗黙的にthisが渡されます.このthisの役割は、オブジェクト内のすべてのメンバー変数を渡すことです.
この点については、「Luaプログラミング」の「対象向け」の章を読んだことのある方が、より深く理解できるかもしれません.
3.static
結果は依然として4で、static変数はメモリを占有しませんか??
いいえ、static変数は静的領域に格納され、通常のメンバー変数とは1つの領域には格納されませんので、依然として4です.
4.virtualを追加
virtualを1つ追加すると、1つの虚関数テーブルポインタが追加されます(複数の虚関数があっても、1つの虚関数テーブルしかありません).
興味深い問題は、1つのポインタが何バイトを占めているのか、4バイトなのかということです.
いいえ、実は機械の文字長と関係があります.32ビットの機械では4バイトで、64ビットの機械では8バイトです.
だから私のコンパイル環境では、この答えは12です.
5.相続の場合
継承する場合、子クラスのバイト数は親クラスに子クラスを加える.
ただし、サブクラスには虚関数テーブルポインタが1つしかなく、親虚関数と子虚関数を指すテーブルであることに注意してください.
そこでインターネットでいくつかの資料を調べて、実験をして、以下のように整理しました.
使用するテスト環境は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つしかなく、親虚関数と子虚関数を指すテーブルであることに注意してください.