2017-03-19 1 views
3

仮想最終機能(基本クラスでfinal)にvtable /仮想コストはありますか?基本クラス(仮想テーブル/仮想コスト)での仮想最終機能のコスト

class B{ 
    public: virtual void fFinal() final{ .... do something ..... } 
    public: void fCheap() { .... do something ..... } 
    public: virtual void fVirtual() { .... do something ..... } 
}; 
class C : public B{ 
    public: virtual void fVirtual() { .... do something ..... } 
}; 

fCheap()またはfVirtual()fFinal() =コストの費用がかかりますか?

ヒューマンエラーを防ぐためにfinal + virtualを使用します(「私を無効にしないでください」)。
fCheap()はまだ親の機能を隠すことができるので、あまり安全ではありません。

以下のリンクからは回答が得られません。

答えて

1

私の知る限り、機能機構は、特定のコンパイラで実装されているか仮想指定されていません。この仮想関数がfinalとしてマークされていても、少なくとも1つの仮想関数があれば、vtableへのポインタをクラスに挿入する可能性が高くなります。

私はあなたのコードスニペットに基づい簡体例をテストしてみた:

class Base { 
    public: 
     virtual void foo() final {} 
}; 

static_assert(sizeof(Base) > 1, "No pointer to vtable"); 

gcc 6.3clang 4.0両方がvtableのへのポインタを追加するようです。

これは、通常の仮想関数を支配するルールが、基本クラスで仮想と最終の両方をマークした関数に適用されることを意味します。その結果、Baseクラスのサイズが大きくなり、BaseクラスまたはBaseから派生したいくつかのクラスへのポインタ/参照を介してfooを呼び出すと、vtableでリダイレクトされるために追加費用がかかります。

+0

vtableが生成されていることを示す証拠があります - >私がvtableのコストを被ることを暗示しますか? – javaLover

+0

@javaLoverはい、そうだと思います。 –

+0

私はこのアイデアを一般化しようとしています。 'D'は単一の関数(非仮想)' f1() 'を持つクラスであるとします。後で、仮想最終関数 'f2()'を追加します。 'f1()'もvtableインダイレクションから遅くなりますか? – javaLover

1

コンパイラの最適化を考慮しない純粋に理論的な観点からは、実際にはfCheap()が最も高速です。 fFinal()fVirtual()の両方とも、vtableを介して呼び出さなければならないため、参照/間接参照が追加されます。 vtableのためオブジェクトサイズも増加しますが、それはfinalとは関係ありません。クラス(またはその基盤の1つ)に仮想関数があればすぐに、そのコストをサイズで支払うことになります。

近代的なオプティマイザ、つまり、非仮想化を入力してください。増加したオブジェクトサイズのコストは消えません。仮想通話のコストがかかる可能性があります。仮想関数を宣言して直ちにそれを最終的にすることは、コンパイラがコンパイル時にどの関数が呼び出されるかを正確に証明することを比較的容易にします。ベットはfFinal()コールで、通常のファンクションコール[1]にデバッグされます。 FVirtual()についても同様のことが起こる可能性がありますが、これは電話サイトの状況によってまったく異なります。

一般に、仮想呼び出しオーバーヘッドは小さいです。実際のコードをプロファイリングしてパフォーマンスのボトルネックになっているという確かな証拠がない限り、あまり心配しないでください。

更新

[1]あなたが賭けに勝つためにどのように可能性が、あなたのコンパイラにそのバージョンと設定を依存しています。確かめる唯一の方法は、実際のコードから生成されたアセンブリを見ることです。私はここで一般的な声明を敢えてするつもりはない。最近のGCCとClangのちょっとしたことをの-O3に行った。私が試したすべての例では、fFinal()がインライン展開されました(与えられた、彼らは些細なことでした)。だから明らかに、どちらのコンパイラもバーチャルなものではありません。 :)

+0

私はget/setとすべてのものにも使うつもりです。これはゲーム向けなので、できるだけ多くの人に最適化しなければならない(最大のfpsに達するために)。 vtableのサイズについて言及していただきありがとうございます。特定の**ベット**の結果を知っている場合は、私にpingしてください。 – javaLover

+0

賭けは非常に重要ではないと判断しました...答えを少し詳細に更新しました。 – besc

関連する問題