2011-01-13 21 views
2

可能性の重複:
How are objects stored in memory in C++?クラスのメモリはC++でどのように処理されますか?

例えばC++クラス:

 
[identifier of A] 
[this is int value] 
[this is void addOne(void)][value++] 

class A{ 
int value; 
void addOne(){ 
    value++; 
} 
}

は、クラスAのインスタンスは、この[擬似コード]のようにロードされますまたは、次のように指定します。

 
[members identifier of A] 
[this is int value]

[functions identifier of A] [this is void addOne(ref to member of A)][A.value++]

2番目に少ないメモリが必要ですあるクラスの複数のインスタンスですべてのインスタンスで同じ関数が使用されるためです。メモリはC++でどのように処理されますか?メモリ操作を変更することは可能ですか?

+0

「Aの識別子」とは何を意味していますか?または "Aのメンバー識別子"? –

+0

実際は申し訳ありませんが、それは適切な複製ではありませんでした。 – GWW

+0

これはあなたの質問に答えますか? http://stackoverflow.com/questions/2006504/c-data-alignment-member-order-inheritance/2007980#2007980 – Beanz

答えて

3

メンバ関数がクラスのインスタンスに格納されているかどうかを確認していますか?いいえ、各インスタンスは同じ関数を使用しますが、[インスタンスの]アドレスは隠しパラメータthisとして渡されます。

+0

これはかなりです。また、typeid()を呼び出さない限り、クラス識別子がどこにも見つからないというメモを追加します。 – Puppy

+0

はい、これは私の質問でした。私はこのような何かを手で行う必要があると思った。ありがとうございました。 – schwer

1

あなたの質問がクラスAのメモリレイアウトに関するものであれば、構造体Aの整数値と同じです。 4バイト(またはそのプラットフォームのintのバイト数)
機能はではなく、のメモリレイアウトの一部です。関数やそれに類するものに格納されたポインタとして扱われるので、クラスのサイズには影響しません。
クラスAがポリモーフィッククラスであった場合、サイズはvtableへのポインタも含むので、サイズは異なります。

1

レイアウトはもっとこのように実際にある:

クラスのインスタンス:他

[this is int value] 

どこか:

ある
[this is void addOne(ref to member of A)][A.value++] 

は、クラスが(正確に)そのメンバ変数で構成され、その基本クラスは何もありません(クラスに仮想関数が含まれていない限り、仮想関数テーブルも含まれます)。特に、 "識別子"はありません。

他の場所に完全に格納され、各クラスインスタンスごとに一度ではなく、その関数と同じです。さらに、クラスの関数はそのクラスへの参照もそのメンバへの参照も含まない。それは単なるメモリブロックのコード(マシンコードステートメント)です。関数を呼び出すときは、クラスインスタンスへのポインタを呼び出しスタックにプッシュした後、その場所にジャンプします(基本的には)。このメソッドは、スタック上のポインタにアクセスしてインスタンス(およびそのメンバー)にアクセスできます。

+0

私は空の行でこれを好きなのです。それをもっとはっきりと書かなければならなかった。 – schwer

0

Randall 'Hyde's Great Code Volume 2(偉大な本、自由な時間があればそれを読んでください)にちょうどそれについて話すセクションがあります。簡単に言えば、クラスがちょうどstructsのような変数を保持しているが、それはそのクラスで宣言された関数へのポインタを保持したレコード(VMT)を持つ:

VMTは、仮想メソッドテーブルの略 及びこれらの4つのバイトはへのポインタが含まれています クラスの「メソッドポインタ」の配列。仮想メソッド(C++の 仮想メンバー関数とも呼ばれます)は、 特殊クラスに関連する関数であり、クラス内のフィールドとして宣言します。 [...]
仮想メンバー関数 を呼び出すには、2つの間接アクセスが必要です。まず、 プログラムは、クラスオブジェクトからVMT ポインタをフェッチし、 を使用して、VMTから特定の 仮想関数アドレスを間接的にフェッチする必要があります。 次に、プログラムは ポインタを介して仮想メンバ の間接呼び出しを、 VMTから取得しなければなりません。
[...]
VMTのコピーはメモリ内に1つしかありません。これは スタティックオブジェクトなので、与えられたクラスタイプのすべてのオブジェクトは同じVMTを共有します。

+1

これは完全に正しいわけではありません。まず、C++では、クラスと構造体のメモリーレイアウトの違いはありません。第二に、質問の例にはvtable/VMTがないため、この説明は誤解を招くものです。 –

+0

@Konrad:私はその本からコピーしました= P – BlackBear

関連する問題