これは実装定義ですが、実際の選択肢はあまりないようです。
まず第一に、あなたが持っている必要があることを見ることができますvptr
または 埋め込まれvtable
た . 後者は、on コンストラクションをコピーする必要がありvtable
、より多くのメモリを消費することを意味しますが、各メソッド呼び出しで 1 つのポインター逆参照を回避できるという利点があります。状況に応じて、おそらくどちらにも適切な議論があります。ほとんどの実装では、ディスパッチ時間を節約する代わりに、構築時間と全体的なメモリ消費を削減することを選択しています。
アプローチを選択vptr
すると、基本クラスと派生クラスのレイアウトのバイナリ互換性を維持する必要があることがわかります。まず第一に、(多くの場合) one を使用してこれを実現できます。互換性の理由からvptr
、これは最も基本的なクラスに存在する必要があります。vptr
単純な継承を処理する場合、派生クラスから基本クラスへの変換の最も簡単な方法は、ポインター値を保持することです。これは、レイアウトが最初に基本クラスのフィールドでなければならず、その後に追加の派生クラスがそれに寄与する必要があることを意味します。
これで、最初にする理由にかなり近づきましたvptr
。オブジェクトの最も基本的な部分内に存在する必要があるため、オブジェクトの先頭近くにある必要があります。
それをオフセット 0 に置く理由は、それがすべてのクラスで利用できる一貫したオフセットだからかもしれません。の前に配置できるデータがあるという保証はありませんvptr
。
をオフセットvptr
0 に配置すると、いくつかの利点もあります。オブジェクトに があるvptr
ことがわかっている場合は、オブジェクトのタイプを知る必要なくオフセット 0 を見なければならないことがわかります (オブジェクトが を持っている以上vptr
)。これは、デバッグ目的で便利です (vtable
多くの場合、実際の型を推測するのに十分な情報が含まれています)。特に、定義済みのオフセットを介してノードtypeid
を取得するために同じオフセットを確認するだけでよいため、 および 同様の実装が簡単になります。type_info
つまり、 の実際のコードを共有できるということですtypeid
。