2012-02-28 3 views
2

すべてのクラスはC++で仮想関数テーブルを持っていますか?すべてのクラスはC++で仮想関数テーブルを持っていますか

私はバーチャルテーブルが多形性であることを知っています。仮想関数を持つクラスにはv-tableが必要です。しかし、クラスは仮想関数を持たないのはどうですか?クラスは基本クラスを持たないのですか?実質的に全てのコンパイラに適用され、親指の非標準ルール(のvtableは、標準によって規定されていない)として

+2

関連:http://stackoverflow.com/questions/7453269/class-with-virtual-functions-takes-more-placeしたがって、短い答えはいいえです。 – Mysticial

+0

標準ではこれが指定されていません。 –

+0

@ LokiAstari:いいえ、しかし、どのクラスがポリモーフィックであるかを指定していますが、実用的なインプリメンテーションではvtableまたはそれと同等のものが唯一のクラスになります。 –

答えて

5

C++の言語仕様では、「vtable」とは何か、またはどのクラスで必要なのかを定義していません。

コンパイラでのC++の特定の実装では、vtableを使用して仮想メソッドを実装することがよくあります。クラスに仮想メソッドがなく(仮想メソッドを持つスーパークラスもない)、コンパイラはvtableを省略することがあります。ただし、これは純粋にコンパイラ実装の決定であり、標準では必要ではないことに注意してください。

+2

説明が明確に実装されていますが、標準のレイアウトタイプのルールはかなり厳しく、コンパイラの自由度はほとんどありません。つまり、標準レイアウトタイプにvtableを含めることはできません。標準レイアウトでルールを破ることになります。 –

+0

@ edA-qamort-ora-y:それが正しいかどうかはわかりません。明らかに、最初のメンバとして 'vptr'を持つことはできません(最初に宣言されたメンバはオフセット0でなければなりません)が、私が見る唯一の問題です。 – MSalters

+0

私はあなたが特別なデータを持つことはできないと信じています。レイアウト互換型間の 'memcpy 'が許されていることと、中間文字バッファを介していることも考慮してください。この追加値によって何らかの形でクラスが識別された場合、その特別な値はクラスの期待値と一致しないため、memcpyを使ってコピーすると基本的にターゲットタイプが破損します。この値を絶対に使用しない場合、それは問題ありませんが、名前のないパディングとまったく同じです。 –

3

のみ仮想メンバ関数および/または仮想デストラクタを持つクラスは、仮想テーブルを有します。他のクラスではありません。これは、C++での一般的なルールに準拠しています。

もちろん、これはあなたに重要な責任を与えます:あなたのクラスはポリモーフィックに削除されていますか?すなわち、それは公の基底クラスとして使用され、それを通して削除されるでしょうか?次に、デストラクタを仮想にします。

2

C++言語では、仮想関数を実装する必要があるかどうかについては言及していません。つまり、vtableやその他のメカニズムを使用することができます。しかし、一般的にはv-tableを使用して実装されており、このv-tableはクラスに仮想関数が含まれている場合にのみ作成されます。

1

v-tableは、関数のアドレスを保持します。このテーブルは、基本クラスで定義されているすべての仮想関数の関数アドレスを保持します。 実際のオブジェクトタイプに基づいて、このアドレスが変更され、正確な関数が呼び出されます。

クラスが仮想関数を持つクラスを継承しない場合は、vテーブルを保持する必要はありません。すべての関数呼び出しはコンパイル時にリンクされます。

関連する問題