このような非常に単純なクラスを作成すると、次のようになります。
class A
{
public :
virtual void foo()
{
}
};
(仮想デストラクタなし)コンパイラはvtableを作成しますか?または、最新のコンパイラは、このケース(コピーアンドペーストが不適切な場合があります)を認識し、そのようなクラスの仮想テーブルを追加しないほど賢いですか?
v-tableは実装の詳細です。仮想関数にvテーブルを使用するコンパイラは、このクラス用にvテーブルを作成します。そうでない人は、そうしません。
コンパイラは、クラスが別のコンパイルユニットで派生していないことを確認できないため、呼び出しがインスタンスの実行時型に正しく依存していることを確認する必要があります。
vtableを使用して仮想呼び出しを解決する場合、vtableが作成されます。別の実装が使用される場合、メカニズムが使用されます。
古いバージョン:コンパイラはクラスが別のコンパイルユニットで派生しないことを確認できないため、vtableが作成されます。
答えは、コンパイラがvテーブルを生成する必要があるということです。理由を理解するには、次のことを検討してください。
class B : public A
{
void foo() { do something interesting }
}
そしてどこか他の場所:
void bar (A& obj)
{
obj.foo()
}
タイプBのオブジェクトを確実に渡すことができbar()
、B::foo()
が呼び出されます。Aを多態的に削除できるため、すべてのポリモーフィッククラスに対して常に仮想デストラクタを使用することをお勧めしますobj
。B
void bar2 (A& obj)
{
delete obj;
}
Bのデストラクタが呼び出されることはないため、おそらく期待どおりに動作しません。