1

重複の可能性:
仮想関数とパフォーマンス-C ++

私はいくつかのクラスを持っています:

class I
{
public:
  virtual void foo() = 0;
protected:
  virtual ~I(){}
};

このクラスはインスタンス削除のインターフェースを提供しないため、デストラクタを保護することは非常に論理的な解決策です。このため、デストラクタを仮想化する必要はありません。しかし、私はそれが仮想化されたコードを持っています。

大きな間違いのようには見えませんが、コードのパフォーマンスにとっては重要ですか?仮想関数を作成するときは、仮想関数テーブルにもう1つのレコードを追加し、仮想呼び出しを行うときは、このテーブルを検索します。つまり、検索時間が長くなるということです。私は正しいですか?

4

3 に答える 3

5

これが問題であったとしても(そうではありません)、いいえ、それは時間を追加しません。ルックアップは、実際に何かをルックアップするランタイムではありません。vftableのサイズは関係ありません。テーブル内のどこにジャンプするかを正確に知っています。

したがって、virtualメソッドの呼び出しにはいくらかのコストがかかります。実際のルックアップにはコストはかかりません。

于 2013-01-06T21:22:53.760 に答える
2

virtual一般に、ポリモーフィッククラスを操作するときは、常にデストラクタを宣言する必要があります。そうしないと、次のような古典的な問題が発生します。

Base *derived = new Derived();
delete derived;

コードに潜在的な問題がある場合と比較して、パフォーマンスに関する心配は確かに無関係です。今日はオブジェクトを削除する必要はありません。おそらく明日は削除します。これを忘れると、微妙なバグが発生することになります。

呼び出しのコストはvirtual存在しますが、1秒間に数百万の仮想メソッドを呼び出さない限り、心配する必要はありません。

vtableでのメソッドのルックアップは実行時の操作ではありませんが、コンパイル時の操作です。コンパイルされると、コードはvtableのどのインデックスが指定されたメソッドによって占有されているかをすでに認識しています。費やされる時間は、vtableから関数のアドレスを取得する間接参照です。

于 2013-01-06T21:24:43.767 に答える
0

良い答え。仮想関数呼び出しのコストは、類人猿の1本の髪の毛のようなものです。

ただし、デストラクタは一般に、データとクラス構造を非常に複雑にしやすいため、低速、仮想、またはそうでない場合があります。そのため、何かを削除すると、気付かなかった27メートルのソフトウェアを実行する可能性があります。をしていました。

于 2013-01-06T23:16:29.167 に答える