これは、説明しているクラスのオブジェクトレイアウトのダンプから直接取得されます。それがあなたの質問に答えることを願っています。もう少し研究して、私vtordisp
はクラスのためにそれを発見しましたBase
。仮想ベースで宣言されたクラスのコンストラクタまたはデストラクタから仮想関数を呼び出すときに使用されるオフセットです。どうやらそれはあなたの仮想関数テーブルがどこにあるかを彼らに知らせるためです。
5年以上前のMSFTのJonathanCavesから:
使用されることはめったにありませんが、ユーザーがコンストラクタまたはデストラクタで仮想関数を呼び出した場合に備えて、仮想基本クラスから継承するクラスに追加し、仮想関数をオーバーライドする必要があります。
注:1>
すべての行の前文について申し訳ありません。Microsoftとそのツールを非難する。
1> class RootBase size(8):
1> +---
1> 0 | {vfptr}
1> 4 | ai
1> +---
1>
1> RootBase::$vftable@:
1> | &RootBase_meta
1> | 0
1> 0 | &RootBase::fas
1>
1> RootBase::fas this adjustor: 0
1>
1>
1> class Base size(24):
1> +---
1> 0 | {vfptr}
1> 4 | {vbptr}
1> 8 | bai
1> +---
1> 12 | (vtordisp for vbase RootBase)
1> +--- (virtual base RootBase)
1> 16 | {vfptr}
1> 20 | ai
1> +---
1>
1> Base::$vftable@Base@:
1> | &Base_meta
1> | 0
1> 0 | &Base::fa
1>
1> Base::$vbtable@:
1> 0 | -4
1> 1 | 12 (Based(Base+4)RootBase)
1>
1> Base::$vftable@RootBase@:
1> | -16
1> 0 | &(vtordisp) Base::fas
1>
1> Base::fas this adjustor: 16
1> Base::fa this adjustor: 0
1>
1> vbi class offset o.vbptr o.vbte fVtorDisp
1> RootBase 16 4 4 1
まったく同じコードを使用しますがRootBase
、通常の基本クラス(つまり、ではなくvirtual public RootBase
)public RootBase
を作成すると、オブジェクトのレイアウトに大きな影響があります。
1> class RootBase size(8):
1> +---
1> 0 | {vfptr}
1> 4 | ai
1> +---
1>
1> RootBase::$vftable@:
1> | &RootBase_meta
1> | 0
1> 0 | &RootBase::fas
1>
1> RootBase::fas this adjustor: 0
1>
1>
1> class Base size(12):
1> +---
1> | +--- (base class RootBase)
1> 0 | | {vfptr}
1> 4 | | ai
1> | +---
1> 8 | bai
1> +---
1>
1> Base::$vftable@:
1> | &Base_meta
1> | 0
1> 0 | &Base::fas
1> 1 | &Base::fa
1>
1> Base::fas this adjustor: 0
1> Base::fa this adjustor: 0
仮想ベースがなくなると、「who-am-i」オフセットが保存されなくなり、オブジェクト形式がかなりきれいにクリーンアップされたように見えることに注意してください。