重複の可能性:
C++ の仮想メカニズムに関する質問
C++で仮想メンバー関数メカニズムを実装する唯一の方法はvtableを使用していますか? 他にどのような方法がありますか?
重複の可能性:
C++ の仮想メカニズムに関する質問
C++で仮想メンバー関数メカニズムを実装する唯一の方法はvtableを使用していますか? 他にどのような方法がありますか?
技術的には、動的ディスパッチに必要なのは、オブジェクトへのポインターが与えられたときに、そのオブジェクトの動的な型を識別する機能だけです。したがって、あらゆる種類の隠し (またはそれほど隠していない) typeidフィールドが機能します。
動的ディスパッチは、その typeid を使用して関連する関数を見つけます。その関連付けは、typeid がインデックスである hastable または配列、またはその他の適切な関係である可能性があります。vptr はたまたま、これを最小限の手順で実現する方法です。
もう 1 つの既知のメカニズムは、型ディスパッチ関数です。事実上、vtable ポインターを typeid (小さな列挙型) に置き換えます。(動的) リンカーは、特定の仮想関数のすべてのオーバーライドを収集し、それらを typeid フィールドの 1 つの大きな switch ステートメントにラップします。
理論的な正当化は、これが間接的なジャンプ (非予測可能) を多くの予測可能なジャンプに置き換えることです。列挙型の値を賢く選択すると、switch ステートメントもかなり効果的になります (つまり、lineair よりも優れています)。
別の可能な実装は、仮想関数へのポインターをオブジェクトに直接格納することです。もちろん、このソリューションが実際に使用されることはありません (少なくとも私が知っている言語では)。これは、メモリ フットプリントの劇的な増加につながるためです。ただし、この実装を使用するコードは、vptr の必要性を抑えることで間接レイヤーを削除するため、実際にはより高速に実行できることに注意してください。
vtable アプローチを使用せずに仮想関数を実装するコンパイラを知りません。
ただし、理論的には、オブジェクト ポインターの内部マップと、 のような仮想関数へのポインターのテーブルをmap<objPtr, functionTable*>
作成して、仮想関数を介して動的ポリモーフィズムを実装することができます。ただし、動的ディスパッチは vtable-approach よりも遅くなります。
vtable-approach は、おそらく動的ポリモーフィズムを実装する最速のメカニズムのようです。たぶん、それがすべてのコンパイラがこのアプローチを採用している理由です!