2016-09-30 5 views
0

クラスのオブジェクトが作成されるたびに、クラスにメモリ空間が割り当てられます。だから私の質問は:メンバーのためだけに作成されたメモリやメンバ関数のためのメモリも?メンバ関数用にメモリが作成されていれば、それらのメモリはどこに格納されますか?メンバ関数はどこに格納されていますか?

+0

(静的でない)メンバー変数 –

答えて

0

クラスのsizeofには、メンバー変数(およびその前後の埋め込み)のみが寄与します。

したがって、通常の機能では、オブジェクトに関する限り、スペースを占有しません。メンバ関数は暗黙的な暗黙的なポインタとして暗黙のthisポインタを持つ通常の静的関数よりも少ししかありません。

しかし、仮想関数テーブルは実装が多態型を扱う方法かもしれませんが、それはいくらかのスペースを占有しますが、おそらくその特定のクラスのすべてのオブジェクトによって使用されるテーブルへのポインタにすぎません。

+0

@BaummitAugen:もちろん正しいです。私はそれを変更しました。 –

+0

それは真実ではありません。多相クラスの各オブジェクトにはvtableへの追加ポインタがあります。オブジェクトのサイズはメンバー、パディング、vtableポインタの合計です –

1

伝統的に実行可能なファイルは、セクションが3つありました。です。 1つは初期化されたデータ用、もう1つは初期化されていないデータ用、もう1つはコード用です。この従来のパーティショニングは依然として非常に使用されており、コードはどこから来ても別のセクションに配置されます。

実行可能ファイルをメモリにロードすると、実行可能ファイルがメモリ内の別の場所に置かれ、実行可能ファイルとしてマークされます(現代のメモリ保護されたシステム)。

0

メンバー関数は、コードセグメント内の単なるコードです。どれくらいのオブジェクトを持っていても、それらは正確に1回存在します。 これらの関数は、最初のパラメーターがthisポインターであることを除いて、通常の関数とほぼ同じです。これは、言語では表示されませんが、実行可能コードのパラメーターとして表示されます。

しかし、メンバ関数の2種類があります。

  1. 「ノーマル」
  2. 仮想

は、彼らが異なって呼ばれているが、コードのサイズ感で、それらの間の違いはありません。通常の関数への呼び出しはコンパイル時に決定され、もう1つは関数ポインタを介した間接呼び出しです

クラスに仮想メンバ関数(クラスは "polymorph")がある場合、コンパイラは "vtable"このクラス(オブジェクトではありません)。

各オブジェクトには、そのクラスのvtableへのポインタが含まれています。オブジェクトが基本クラス型のポインタによってアクセスされる場合、これは正しい仮想関数にアクセスするために必要です。

例:

class A{ 
public: bool doSomething(); 
int i; 
}; 

class B:public A { 
public: bool doSomething(); 
int j; 
} 

// 
B b; 
A* a = &b; 
a->doSomething(); // <- A::doSomething() is called; 
// 

このクラスのどちらものvtableを必要とします。

例2:

class A{ 
public: virtual bool doSomething(); 
int i; 
}; 

class B:public A { 
public: bool doSomething(); 
int j; 
} 

// 
B b; 
A* a = &b; 
a->doSomething(); // <- B::doSomething() is called; 
// 

A(およびそのすべてのチャイルズ)のvtableを得ます。次にオブジェクトが作成され、オブジェクトのvtableポインタが正しいテーブルに設定され、ポインタのタイプとは関係なく、正しい関数が呼び出されます。

関連する問題