2012-04-30 7 views
2

私は、正確に仮想関数テーブルがC++クラスのどこに格納されるのかを調べようとしました。 私はそのような "関数ポインタの静的配列"のような答えを見つけました それはデータセグメントの読み取り専用メモリに格納されますか? (初期化されたもの)C++クラスの仮想関数テーブルはどこに格納されていますか?

+7

実装定義です。標準では、vtable _at all_が存在する必要もなく、実行可能であると判明した場合、コンパイラは他の方法で仮想継承を実装できます。 – leftaroundabout

答えて

2

おそらくはい。しかし、それは強制されていません。仮想ファンクションテーブルを介して多態性が実装されていることは必須ではありませんが、ほとんどのプラットフォームではそうです。これらは実装の詳細です。コンパイラが標準によって設定された動作に従う限り、必要なものは何でも実行できます。

vftableはクラスごとに1つで、メモリ内の1つの場所にのみ格納されます。

+0

実行時の多型を達成するためにコンパイラが使用できる他の方法は何ですか? – saumitra

+0

@saumitraは効率的ではありませんが、それぞれのインスタンスはメソッドへのポインタのコレクションを持つことができます。 –

+0

「メモリ内の1つの場所のみ」は一般的ですが、確かに普遍的ではありません。 DLLを使用すると、複数のコピーを作成することができます。うまくいけば同じですが、ODR違反とその未定義の動作はひどくこれを破る可能性があります。 – MSalters

1

仮想関数を作成すると、コンパイラはクラス内にvptrを挿入します。その結果、クラスのサイズは4バイト(Win32上)に増加します。このポインタは仮想テーブル(vtable)のアドレスを保持します。 vtableはコンパイル時にコンパイラによって構築され、基本的には関数ポインタの配列にすぎません。関数ポインタは実際にその特定のクラスの仮想関数へのポインタです。より正確には、仮想テーブルは関数ポインタの静的な配列なので、同じクラスの異なるインスタンスがそのvtableを共有することができます。静的メンバーはデータセクション(.data)に格納されるため、vtableも実行可能ファイルのデータセクションに格納されます。

0

実装に依存します。はい。

g ++(4.9.0)の場合、仮想テーブル(ポインタではない)はELFファイルのセクション.rodataとそれに対応するセグメントLOADをメモリに格納します。

関連する問題