2011-01-06 20 views
4

C++仕様の私の(限られた)知識によれば、仮想メンバを持つクラスのvtableは、最初の非純粋な非インライン仮想メソッドの定義に置かれます。コンパイラは、すべての純粋仮想メソッド(例えば、インタフェース)を持つクラスから継承するクラスをどのように処理するのですか?この場合、vtableはどこに配置されていますか?完全に純粋な仮想クラスのVtableの配置

+3

C++の仕様自体にはvtablesのことは何も言われていません。 –

+1

重い実装の詳細。 MSVC++には、このようなvtableを抑制する__declspec(novtable)があります。同じことをするための非標準の__interfaceキーワード。 –

答えて

5

vtableには、実装された仮想メソッドのアドレスが格納されます。クラスのすべてのメソッドが純粋仮想であり、どれも実装されていない場合は、vtableを生成する必要はありません。

クラスから派生してメソッドを実装することなく、そのようなクラスをあまり使用することはできませんでした。実装された仮想メソッドを持つ各クラスには、すべての仮想メソッドのアドレスを含む独自のvtableがあります。基本クラスのvtableは決して参照しません。アドレスは複製されます。したがって、別のクラスから継承するクラスがある場合、そのクラスは独自のvtableだけを使用します。基本クラスのvtableは気にしません。このvtableは存在する必要もありません。

C++仕様自体はvtableについて何も言及していません。それらは単に一般的になっているコンパイラの動作です。

+0

興味深い。重複したテーブルを持つと、あるソート定義ルールに違反していると思ったでしょう。 – tgoodhart

+0

テーブルが重複していません。新しいテーブルは、そのクラスによって仮想メソッドが実装されている場合にのみ生成されます。これは、その実装へのポインタを含む一意のvtableを作成します。テーブルには、変更されていない仮想メソッドの重複アドレスが含まれます。 – fuzzyTew

+1

クラスのすべてのメソッドが純粋仮想である場合、実装されていませんこれはちょうど真実ではありません。 C++では、純粋仮想が実装されていないわけではありません。 –

2

私の限られた知識によれば、インスタンスがあるまではvtableは必要ありません。

+0

どのようなインスタンスですか?純粋仮想関数が別のTUで定義された実装を持つかどうかを問わず、コンパイラは単一のTUをコンパイルする際には分かりません。コンパイラの実装者は、どのように対処するかを決めることができ、未定義の純粋仮想関数への不正な呼び出しを報告するためにvtableを作成し、エラー関数へのポインタを設定することは合理的な解決策になります。 –

3

C++標準では、vtableの配置、またはvテーブルの存在については何も指定していません。それは振る舞いを指定するだけであり、v表は最も直接的な実装であるため、広く使用されています。

抽象クラスのvテーブルが存在する理由の1つは、オブジェクトの動的な型が抽象クラスである場合に、構築および破棄中に使用されるためです。

純粋な仮想関数のみを持つクラスでは、コンストラクタが存在しない可能性があります(コンストラクタは仮想にできないため)。しかし、デストラクタは確かに仮想である可能性があります。

クラスに実装済みのpure virtual destructorがまだ存在していて、次にvテーブル(または同等の実装の詳細)が必要です。

しかし、純粋仮想関数の実装はまれであり、インタフェースを定義するときには実行されません。

関連する問題