2

私はC++と仮想継承、特にベースクラスと子クラスの間でvtableの競合が解決される方法に興味がありました。それらがどのように機能するかについての詳細を理解するふりをするつもりはありませんが、これまで私が輝いていたのは、それらがその解像度による仮想関数の使用によって引き起こされる小さな遅延であるということです。私の質問は、基本クラスが空白であるかどうかです。つまり、その仮想関数は次のように定義されます。

virtual void doStuff() = 0;

これは、選択できる関数のセットが1つしかないため、解像度が不要であることを意味しますか?

これがばかげた質問である場合は、私を許してください-私が言ったように、私はvtablesがどのように機能するかを理解していないので、私は本当にこれ以上よくわかりません。

編集

したがって、2つの別個の子クラスを持つ抽象クラスがある場合:

    A
   / \
  /   \
 B     C

子クラスから関数を呼び出すときに、単一の継承のないクラスと比較して、パフォーマンスへの影響はありませんか?

4

3 に答える 3

5

子クラスで非仮想関数を呼び出してもヒットしません。例のように純粋仮想関数のオーバーライドされたバージョンを呼び出している場合、仮想ペナルティがまだ存在する可能性があります。一般に、問題のオブジェクトの正確な値渡し型を (コンテキストから) 知っている非常に特殊な状況を除いて、コンパイラが仮想テーブルの使用を最適化することは困難です。

しかし、真剣にオーバーヘッドを心配する必要はありません。実際には、それがコードの一部であり、パフォーマンスのボトルネックを引き起こしている状況に遭遇することはほとんどないでしょう。設計にとって意味のある仮想関数を使用し、(わずかな) パフォーマンスの低下を心配する必要はありません。

于 2010-06-18T15:09:59.233 に答える
2

あなたが話している「1セットの機能」が何であるかわかりません。2 つの派生クラスがBありC、それぞれに独自の仮想関数セットがあります。したがって、すべての関数が純粋であっても、少なくとも2 つのセットがあります。A

仮想ディスパッチは、コンパイラが処理中のオブジェクトの動的な型を認識していない場合に発生します。たとえば、 pointer がある場合、 typeまたは typeA *pのオブジェクトを指すことができます。オブジェクトが指している実際の型が何であるかをコンパイラが認識していない場合、 を介して仮想関数を呼び出すために、仮想ディスパッチを使用する必要があります。BCpp

PSあなたの例には「仮想継承」はありません。C++ における仮想継承という用語には、独自の意味があります。そして、ここでは仮想継承について話しているのではありません。

于 2010-06-18T14:39:31.617 に答える
0

「ダブルディスパッチ」ヒットは、メソッドが仮想の場合にのみ発生します。派生メソッドが仮想でない場合、パフォーマンスへの影響はありません。

于 2010-06-18T14:11:27.683 に答える