VTable のコンテキストでの仮想メソッド呼び出しと直接メソッド呼び出しの違いは何ですか? Virtual & Direct Call の場合、メソッド参照はどのように解決されますか?
2 に答える
理論的には、そのようなものは存在せず、C++ 標準では定義されていません (仮想呼び出しは定義されていますが、それらがどのように機能するかは指定されておらず、VTable などは存在しません)。
実際には、仮想呼び出しは、私が知っているすべてのコンパイラで vtable を使用します。これは、仮想メンバー (インスタンスごとではなくクラスごと) を持つクラスごとに 1 つのアドレス テーブルと、インスタンスごとにそのテーブルへの 1 つのポインターのメモリ オーバーヘッドです。
仮想呼び出しは、アーキテクチャに応じて、そのテーブルからのロードに続いてロードされたアドレスへの呼び出し、またはいわゆる間接呼び出し (同じですが、1 つの命令内) のいずれかです。
直接呼び出しは、コンパイラが認識しているアドレスへの単純な通常の関数呼び出し (単一の命令) です (共有ライブラリ呼び出しにはいくつかの例外があり、間接呼び出しや二重間接呼び出しも使用される場合があります)。コンパイラがオブジェクトのランタイム タイプについて 100% 確実である場合、またはスコープ解決 ( operator::
) を介して明示的に伝える場合は常に、それが使用されます。
直接呼び出しと間接呼び出しの大きな違いは、伝統的に分岐予測とパイプライン処理であり、間接呼び出しははるかにコストがかかります (10 ~ 15 倍) が、最近の CPU ではどちらの場合でも同様にうまく実装されています (最新の CPU には専用の間接呼び出しキャッシュがあります)。 CPU)。
違いが存在しない、または無視できるほどであるとまでは言いませんが、今日では大したことではありません.