5

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

4

3 に答える 3

6

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

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

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

2020年からの編集:私はこれをほぼ10年前に書きました。記憶と個人的な経験から書いたと思います。以下の 2 つのコメントは、コンパイラ(エラーをスローするために) 基本クラスの vtable を作成することを示しています。2011 年以降、誰も何も追加していないようです。私は今、認知機能が低下しており、あまり多くを考えることが難しくなっています。ここでの詳細が重要な場合は、独自の調査を行ってください。

于 2011-01-06T18:12:18.543 に答える
3

C++ 標準では、vtable の配置や v-table の存在についても何も指定されていません。動作を指定するだけで、v-table はたまたま最も簡単な実装であるため、広く使用されています。

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

純粋な仮想関数のみを持つクラスでは、明らかにコンストラクターは存在できません (コンストラクターは仮想化できないため)。ただし、デストラクタは確かに仮想にすることができます。

あなたのクラスはまだ実装を伴う純粋な仮想デストラクタを持っている可能性があり、その場合は v-table (または同等の実装の詳細) が必要です。

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

于 2011-01-06T18:31:19.113 に答える
2

インスタンスができるまで、vtable は必要ありません。

于 2011-01-06T18:06:25.923 に答える