VTable の構造、順序と内容、およびオブジェクト内の vtable ポインタの場所の詳細を探しています。
理想的には、これは単一継承、多重継承、および仮想継承をカバーします。
外部ドキュメントへの参照も歓迎します
GCC 4.0x クラス レイアウトのドキュメントはここにあり、Itanium、およびより広範な GNU、ABI レイアウト ドキュメントはここにあります。
仮想テーブルは通常、関数ポインターの配列として扱われますが、コンパイラーはデータ ポインター (MI および VI シナリオの場合、または typeinfos へ)、整数 (フィックスアップ用)、またはセンチネル要素 (NULL ポインターなど) を自由に配置できます。同じように。レイアウトは通常、コンパイラ固有 (または複数の C++ コンパイラが ABI を共有する場合は ABI 固有) ですが、コンパイルされるクラスに安定したインターフェイスがある場合は安定しています (そうでない場合は、常にコードを再コンパイルする必要があり、それは面倒です)。 . また、仮想および多重継承を含むコーナー ケースを処理するために必要な追加のテーブルもあり、派生クラスの構築中の仮想呼び出しが、それらの状況下で標準で規定されているとおりに動作することを確認します (これらは、以下の出力は用です)。
GCC 4.x の特定のケースに関しては、-fdump-class-hierarchy
スイッチは実際に説明されているとおりに機能します (そしていくつか)。以下のサンプルコードを使用して、 Coliruでテストしました。
struct Base
{
virtual ~Base() {}
virtual void f() = 0;
};
struct OtherBase
{
virtual ~OtherBase() {}
virtual void g() {}
};
struct Derived: public Base
{
virtual ~Derived() {}
virtual void f() {}
};
struct MultiplyDerived: public Base, public OtherBase
{
virtual ~MultiplyDerived() {}
virtual void f() {}
virtual void g() {}
};
struct OtherDerived: public Base
{
virtual ~OtherDerived() {}
virtual void f() {}
};
struct DiamondDerived: public Derived, public OtherDerived
{
virtual ~DiamondDerived() {}
virtual void f() {}
};
struct VirtuallyDerived: virtual public Base
{
virtual ~VirtuallyDerived() {}
virtual void f() {}
};
struct OtherVirtuallyDerived: virtual public Base
{
virtual ~OtherVirtuallyDerived() {}
virtual void f() {}
};
struct VirtuallyDiamondDerived: public VirtuallyDerived, public OtherVirtuallyDerived
{
virtual ~VirtuallyDiamondDerived() {}
virtual void f() {}
};
struct DoublyVirtuallyDiamondDerived: virtual public VirtuallyDerived, virtual public OtherVirtuallyDerived
{
virtual ~DoublyVirtuallyDiamondDerived() {}
virtual void f() {}
};
struct MixedVirtuallyDerived: virtual public Base, public OtherBase
{
virtual ~MixedVirtuallyDerived() {}
};
struct MixedVirtuallyDiamondDerived: public VirtuallyDerived, public MixedVirtuallyDerived
{
virtual ~MixedVirtuallyDiamondDerived() {}
virtual void f() {}
virtual void g() {}
};
struct VirtuallyMultiplyDerived: virtual public Base, virtual public OtherBase
{
virtual ~VirtuallyMultiplyDerived() {}
};
struct OtherVirtuallyMultiplyDerived: virtual public Base, virtual public OtherBase
{
virtual ~OtherVirtuallyMultiplyDerived() {}
};
struct MultiplyVirtuallyDiamondDerived: public VirtuallyMultiplyDerived, public OtherVirtuallyMultiplyDerived
{
virtual ~MultiplyVirtuallyDiamondDerived() {}
virtual void f() {}
virtual void g() {}
};
および G++ から受け取ったもの (マングルされた名前のガイド: TI は typeinfo、TV は vtable、Th と Tv はサンクで、多重および/または仮想継承の存在下で正しい仮想呼び出しを行うために使用されます):
Base の Vtable Base::_ZTV4Base: 5u エントリ 0 (整数 (*)(...))0 8 (整数 (*)(...))(& _ZTI4Base) 16 0u 24 0u 32 (整数 (*)(...))__cxa_pure_virtual クラスベース サイズ=8 整列=8 ベースサイズ=8 ベースアライン=8 ベース (0x0x7fd42c0355a0) 0 ほぼ空 vptr=((& Base::_ZTV4Base) + 16u) OtherBase の Vtable OtherBase::_ZTV9OtherBase: 5u エントリ 0 (整数 (*)(...))0 8 (整数 (*)(...))(& _ZTI9OtherBase) 16 (int (*)(...))OtherBase::~OtherBase 24 (int (*)(...))OtherBase::~OtherBase 32 (整数 (*)(...))OtherBase::g クラス OtherBase サイズ=8 整列=8 ベースサイズ=8 ベースアライン=8 OtherBase (0x0x7fd42c035600) 0 ほぼ空 vptr=((& その他のベース::_ZTV9その他のベース) + 16u) 派生用の Vtable 派生::_ZTV7派生: 5u エントリ 0 (整数 (*)(...))0 8 (int (*)(...))(& _ZTI7Derived) 16 (int (*)(...))Derived::~Derived 24 (int (*)(...))Derived::~Derived 32 (int (*)(...))Derived::f 派生クラス サイズ=8 整列=8 ベースサイズ=8 ベースアライン=8 派生 (0x0x7fd42c02d138) 0 ほとんど空 vptr=((&派生::_ZTV7派生) + 16u) ベース (0x0x7fd42c035660) 0 ほとんど空 派生用プライマリ (0x0x7fd42c02d138) MultiplyDerived の Vtable MultiplyDerived::_ZTV15MultiplyDerived: 11u エントリ 0 (整数 (*)(...))0 8 (int (*)(...))(& _ZTI15MultiplyDerived) 16 (int (*)(...))MultiplyDerived::~MultiplyDerived 24 (int (*)(...))MultiplyDerived::~MultiplyDerived 32 (int (*)(...))MultiplyDerived::f 40 (int (*)(...))MultiplyDerived::g 48 (整数 (*)(...))-8 56 (int (*)(...))(& _ZTI15MultiplyDerived) 64 (int (*)(...))MultiplyDerived::_ZThn8_N15MultiplyDerivedD1Ev 72 (int (*)(...))MultiplyDerived::_ZThn8_N15MultiplyDerivedD0Ev 80 (int (*)(...))MultiplyDerived::_ZThn8_N15MultiplyDerived1gEv クラス MultiplyDerived サイズ=16 整列=8 base size=16 base align=8 MultiplyDerived (0x0x7fd42c04aaf0) 0 vptr=((& MultiplyDerived::_ZTV15MultiplyDerived) + 16u) ベース (0x0x7fd42c0356c0) 0 ほとんど空 MultiplyDerived のプライマリ (0x0x7fd42c04aaf0) OtherBase (0x0x7fd42c035720) 8 ほとんど空 vptr=((& MultiplyDerived::_ZTV15MultiplyDerived) + 64u) OtherDerived の Vtable OtherDerived::_ZTV12OtherDerived: 5u エントリ 0 (整数 (*)(...))0 8 (int (*)(...))(& _ZTI12OtherDerived) 16 (int (*)(...))OtherDerived::~OtherDerived 24 (int (*)(...))OtherDerived::~OtherDerived 32 (int (*)(...))OtherDerived::f クラス OtherDerived サイズ=8 整列=8 ベースサイズ=8 ベースアライン=8 OtherDerived (0x0x7fd42c02d1a0) 0 ほぼ空 vptr=((& OtherDerived::_ZTV12OtherDerived) + 16u) ベース (0x0x7fd42c035780) 0 ほとんど空 プライマリ - OtherDerived (0x0x7fd42c02d1a0) DiamondDerived の Vtable DiamondDerived::_ZTV14DiamondDerived: 10u エントリ 0 (整数 (*)(...))0 8 (int (*)(...))(& _ZTI14DiamondDerived) 16 (int (*)(...))DiamondDerived::~DiamondDerived 24 (int (*)(...))DiamondDerived::~DiamondDerived 32 (int (*)(...))DiamondDerived::f 40 (整数 (*)(...))-8 48 (int (*)(...))(& _ZTI14DiamondDerived) 56 (int (*)(...))DiamondDerived::_ZThn8_N14DiamondDerivedD1Ev 64 (int (*)(...))DiamondDerived::_ZThn8_N14DiamondDerivedD0Ev 72 (int (*)(...))DiamondDerived::_ZThn8_N14DiamondDerived1fEv クラス DiamondDerived サイズ=16 整列=8 base size=16 base align=8 DiamondDerived (0x0x7fd42c0625b0) 0 vptr=((& DiamondDerived::_ZTV14DiamondDerived) + 16u) 派生 (0x0x7fd42c02d208) 0 ほとんど空 Primary-DiamondDerived (0x0x7fd42c0625b0) の場合 ベース (0x0x7fd42c0357e0) 0 ほぼ空 派生用プライマリ (0x0x7fd42c02d208) OtherDerived (0x0x7fd42c02d270) 8 ほとんど空 vptr=((& DiamondDerived::_ZTV14DiamondDerived) + 56u) ベース (0x0x7fd42c035840) 8 ほとんど空 プライマリ - OtherDerived (0x0x7fd42c02d270) VirtuallyDerived の Vtable VirtuallyDerived::_ZTV16VirtuallyDerived: 8u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI16VirtuallyDerived) 40 (int (*)(...))VirtuallyDerived::~VirtuallyDerived 48 (int (*)(...))VirtuallyDerived::~VirtuallyDerived 56 (int (*)(...))VirtuallyDerived::f VirtuallyDerived の VTT VirtuallyDerived::_ZTT16VirtuallyDerived: 2u エントリ 0 ((& VirtuallyDerived::_ZTV16VirtuallyDerived) + 40u) 8 ((& VirtuallyDerived::_ZTV16VirtuallyDerived) + 40u) クラス VirtuallyDerived サイズ=8 整列=8 ベースサイズ=8 ベースアライン=8 VirtuallyDerived (0x0x7fd42c02d2d8) 0 ほとんど空 vptridx=0u vptr=((& VirtuallyDerived::_ZTV16VirtuallyDerived) + 40u) ベース (0x0x7fd42c0358a0) 0 ほぼ空の仮想 primary-for VirtuallyDerived (0x0x7fd42c02d2d8) vptridx=8u vbaseoffset=-40 OtherVirtuallyDerived の Vtable OtherVirtuallyDerived::_ZTV21OtherVirtuallyDerived: 8u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI21OtherVirtuallyDerived) 40 (int (*)(...))OtherVirtuallyDerived::~OtherVirtuallyDerived 48 (int (*)(...))OtherVirtuallyDerived::~OtherVirtuallyDerived 56 (int (*)(...))OtherVirtuallyDerived::f OtherVirtuallyDerived の VTT OtherVirtuallyDerived::_ZTT21OtherVirtuallyDerived: 2u エントリ 0 ((& OtherVirtuallyDerived::_ZTV21OtherVirtuallyDerived) + 40u) 8 ((& OtherVirtuallyDerived::_ZTV21OtherVirtuallyDerived) + 40u) クラス OtherVirtuallyDerived サイズ=8 整列=8 ベースサイズ=8 ベースアライン=8 OtherVirtuallyDerived (0x0x7fd42c02d340) 0 ほぼ空 vptridx=0u vptr=((& OtherVirtuallyDerived::_ZTV21OtherVirtuallyDerived) + 40u) ベース (0x0x7fd42c035900) 0 ほぼ空の仮想 primary-for OtherVirtuallyDerived (0x0x7fd42c02d340) vptridx=8u vbaseoffset=-40 VirtuallyDiamondDerived の Vtable VirtuallyDiamondDerived::_ZTV23VirtuallyDiamondDerived: 16u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI23VirtuallyDiamondDerived) 40 (int (*)(...))VirtuallyDiamondDerived::~VirtuallyDiamondDerived 48 (int (*)(...))VirtuallyDiamondDerived::~VirtuallyDiamondDerived 56 (int (*)(...))VirtuallyDiamondDerived::f 64 18446744073709551608u 72 18446744073709551608u 80 18446744073709551608u 88 (整数 (*)(...))-8 96 (int (*)(...))(& _ZTI23VirtuallyDiamondDerived) 104 (int (*)(...))VirtuallyDiamondDerived::_ZThn8_N23VirtuallyDiamondDerivedD1Ev 112 (int (*)(...))VirtuallyDiamondDerived::_ZThn8_N23VirtuallyDiamondDerivedD0Ev 120 (int (*)(...))VirtuallyDiamondDerived::_ZThn8_N23VirtuallyDiamondDerived1fEv VirtuallyDiamondDerived の VirtuallyDerived (0x0x7fd42c02d3a8 インスタンス) の構築 vtable VirtuallyDiamondDerived::_ZTC23VirtuallyDiamondDerived0_16VirtuallyDerived: 8u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI16VirtuallyDerived) 40 0u 48 0u 56 (int (*)(...))VirtuallyDerived::f VirtuallyDiamondDerived の OtherVirtuallyDerived (0x0x7fd42c02d410 インスタンス) の構築 vtable VirtuallyDiamondDerived::_ZTC23VirtuallyDiamondDerived8_21OtherVirtuallyDerived: 15u エントリ 0 18446744073709551608u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI21OtherVirtuallyDerived) 40 0u 48 0u 56 (int (*)(...))OtherVirtuallyDerived::f 64 8u 72 8u 80 (整数 (*)(...))8 88 (int (*)(...))(& _ZTI21OtherVirtuallyDerived) 96 0u 104 0u 112 (int (*)(...))OtherVirtuallyDerived::_ZTv0_n32_N21OtherVirtuallyDerived1fEv VirtuallyDiamondDerived の VTT VirtuallyDiamondDerived::_ZTT23VirtuallyDiamondDerived: 7u エントリ 0 ((& VirtuallyDiamondDerived::_ZTV23VirtuallyDiamondDerived) + 40u) 8 ((& VirtuallyDiamondDerived::_ZTC23VirtuallyDiamondDerived0_16VirtuallyDerived) + 40u) 16 ((& VirtuallyDiamondDerived::_ZTC23VirtuallyDiamondDerived0_16VirtuallyDerived) + 40u) 24 ((& VirtuallyDiamondDerived::_ZTC23VirtuallyDiamondDerived8_21OtherVirtuallyDerived) + 40u) 32 ((& VirtuallyDiamondDerived::_ZTC23VirtuallyDiamondDerived8_21OtherVirtuallyDerived) + 96u) 40 ((& VirtuallyDiamondDerived::_ZTV23VirtuallyDiamondDerived) + 40u) 48 ((& VirtuallyDiamondDerived::_ZTV23VirtuallyDiamondDerived) + 104u) クラス VirtuallyDiamondDerived サイズ=16 整列=8 base size=16 base align=8 VirtuallyDiamondDerived (0x0x7fd42c07e460) 0 vptridx=0u vptr=((& VirtuallyDiamondDerived::_ZTV23VirtuallyDiamondDerived) + 40u) VirtuallyDerived (0x0x7fd42c02d3a8) 0 ほとんど空 プライマリ-VirtuallyDiamondDerived (0x0x7fd42c07e460) subvttidx=8u ベース (0x0x7fd42c035960) 0 ほぼ空の仮想 primary-for VirtuallyDerived (0x0x7fd42c02d3a8) vptridx=40u vbaseoffset=-40 OtherVirtuallyDerived (0x0x7fd42c02d410) 8 ほとんど空 失われたプライマリ subvttidx=24u vptridx=48u vptr=((& VirtuallyDiamondDerived::_ZTV23VirtuallyDiamondDerived) + 104u) ベース (0x0x7fd42c035960) 代替パス DoublelyVirtuallyDiamondDerived の Vtable DoublyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived: 18u エントリ 0 8u 8 0u 16 0u 24 0u 32 0u 40 (整数 (*)(...))0 48 (int (*)(...))(& _ZTI29DoublyVirtuallyDiamondDerived) 56 (int (*)(...))DoublyVirtuallyDiamondDerived::~DoublyVirtuallyDiamondDerived 64 (int (*)(...))DoublyVirtuallyDiamondDerived::~DoublyVirtuallyDiamondDerived 72 (int (*)(...))DoublyVirtuallyDiamondDerived::f 80 18446744073709551608u 88 18446744073709551608u 96 18446744073709551608u 104 (整数 (*)(...))-8 112 (int (*)(...))(& _ZTI29DoublyVirtuallyDiamondDerived) 120 (int (*)(...))DoublyVirtuallyDiamondDerived::_ZTv0_n24_N29DoublyVirtuallyDiamondDerivedD1Ev 128 (int (*)(...))DoublyVirtuallyDiamondDerived::_ZTv0_n24_N29DoublyVirtuallyDiamondDerivedD0Ev 136 (int (*)(...))DoublyVirtuallyDiamondDerived::_ZTv0_n32_N29DoublyVirtuallyDiamondDerived1fEv DoublelyVirtuallyDiamondDerived の VirtuallyDerived の構築 vtable DoublyVirtuallyDiamondDerived::_ZTC29DoublyVirtuallyDiamondDerived0_16VirtuallyDerived: 8u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI16VirtuallyDerived) 40 0u 48 0u 56 (int (*)(...))VirtuallyDerived::f DoublyVirtuallyDiamondDerived の OtherVirtuallyDerived の構築 vtable DoublyVirtuallyDiamondDerived::_ZTC29DoublyVirtuallyDiamondDerived8_21OtherVirtuallyDerived: 15u エントリ 0 18446744073709551608u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI21OtherVirtuallyDerived) 40 0u 48 0u 56 (int (*)(...))OtherVirtuallyDerived::f 64 8u 72 8u 80 (整数 (*)(...))8 88 (int (*)(...))(& _ZTI21OtherVirtuallyDerived) 96 0u 104 0u 112 (int (*)(...))OtherVirtuallyDerived::_ZTv0_n32_N21OtherVirtuallyDerived1fEv DoublelyVirtuallyDiamondDerived の VTT DoublyVirtuallyDiamondDerived::_ZTT29DoublyVirtuallyDiamondDerived: 8u エントリ 0 ((& DoublyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived) + 56u) 8 ((& DoublelyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived) + 56u) 16 ((& DoublelyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived) + 56u) 24 ((& DoublelyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived) + 120u) 32 ((& DoublelyVirtuallyDiamondDerived::_ZTC29DoublyVirtuallyDiamondDerived0_16VirtuallyDerived) + 40u) 40 ((& DoublelyVirtuallyDiamondDerived::_ZTC29DoublyVirtuallyDiamondDerived0_16VirtuallyDerived) + 40u) 48 ((& DoublyVirtuallyDiamondDerived::_ZTC29DoublyVirtuallyDiamondDerived8_21OtherVirtuallyDerived) + 40u) 56 ((& DoublyVirtuallyDiamondDerived::_ZTC29DoublyVirtuallyDiamondDerived8_21OtherVirtuallyDerived) + 96u) クラス DoublelyVirtuallyDiamondDerived サイズ=16 整列=8 ベースサイズ=8 ベースアライン=8 DoublyVirtuallyDiamondDerived (0x0x7fd42c07ea10) 0 ほぼ空 vptridx=0u vptr=((& DoublyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived) + 56u) VirtuallyDerived (0x0x7fd42c02d478) 0 ほぼ空の仮想 primary-for DoublelyVirtuallyDiamondDerived (0x0x7fd42c07ea10) subvttidx=32u vptridx=8u vbaseoffset=-48 ベース (0x0x7fd42c035a80) 0 ほぼ空の仮想 primary-for VirtuallyDerived (0x0x7fd42c02d478) vptridx=16u vbaseoffset=-40 OtherVirtuallyDerived (0x0x7fd42c02d4e0) 8 ほぼ空の仮想 失われたプライマリ subvttidx=48u vptridx=24u vbaseoffset=-56 vptr=((& DoublyVirtuallyDiamondDerived::_ZTV29DoublyVirtuallyDiamondDerived) + 120u) ベース (0x0x7fd42c035a80) 代替パス MixedVirtuallyDerived の Vtable MixedVirtuallyDerived::_ZTV21MixedVirtuallyDerived: 13u エントリ 0 8u 8 (整数 (*)(...))0 16 (int (*)(...))(& _ZTI21MixedVirtuallyDerived) 24 0u 32 0u 40 (整数 (*)(...))OtherBase::g 48 0u 56 18446744073709551608u 64 (整数 (*)(...))-8 72 (int (*)(...))(& _ZTI21MixedVirtuallyDerived) 80 0u 88 0u 96 (整数 (*)(...))__cxa_pure_virtual MixedVirtuallyDerived の VTT MixedVirtuallyDerived::_ZTT21MixedVirtuallyDerived: 2u エントリ 0 ((& MixedVirtuallyDerived::_ZTV21MixedVirtuallyDerived) + 24u) 8 ((& MixedVirtuallyDerived::_ZTV21MixedVirtuallyDerived) + 80u) クラス MixedVirtuallyDerived サイズ=16 整列=8 ベースサイズ=8 ベースアライン=8 MixedVirtuallyDerived (0x0x7fd42c07eee0) 0 ほぼ空 vptridx=0u vptr=((& MixedVirtuallyDerived::_ZTV21MixedVirtuallyDerived) + 24u) ベース (0x0x7fd42c035c60) 8 ほぼ空の仮想 vptridx=8u vbaseoffset=-24 vptr=((& MixedVirtuallyDerived::_ZTV21MixedVirtuallyDerived) + 80u) OtherBase (0x0x7fd42c035cc0) 0 ほぼ空 プライマリ-MixedVirtuallyDerived 用 (0x0x7fd42c07eee0) MixedVirtuallyDiamondDerived の Vtable MixedVirtuallyDiamondDerived::_ZTV28MixedVirtuallyDiamondDerived: 15u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI28MixedVirtuallyDiamondDerived) 40 (int (*)(...))MixedVirtuallyDiamondDerived::~MixedVirtuallyDiamondDerived 48 (int (*)(...))MixedVirtuallyDiamondDerived::~MixedVirtuallyDiamondDerived 56 (int (*)(...))MixedVirtuallyDiamondDerived::f 64 (int (*)(...))MixedVirtuallyDiamondDerived::g 72 18446744073709551608u 80 (整数 (*)(...))-8 88 (int (*)(...))(& _ZTI28MixedVirtuallyDiamondDerived) 96 (int (*)(...))MixedVirtuallyDiamondDerived::_ZThn8_N28MixedVirtuallyDiamondDerivedD1Ev 104 (int (*)(...))MixedVirtuallyDiamondDerived::_ZThn8_N28MixedVirtuallyDiamondDerivedD0Ev 112 (int (*)(...))MixedVirtuallyDiamondDerived::_ZThn8_N28MixedVirtuallyDiamondDerived1gEv MixedVirtuallyDiamondDerived の VirtuallyDerived (0x0x7fd42c02d750 インスタンス) の構築 vtable MixedVirtuallyDiamondDerived::_ZTC28MixedVirtuallyDiamondDerived0_16VirtuallyDerived: 8u エントリ 0 0u 8 0u 16 0u 24 (整数 (*)(...))0 32 (int (*)(...))(& _ZTI16VirtuallyDerived) 40 0u 48 0u 56 (int (*)(...))VirtuallyDerived::f MixedVirtuallyDiamondDerived の MixedVirtuallyDerived (0x0x7fd42c0b5380 インスタンス) の構築 vtable MixedVirtuallyDiamondDerived::_ZTC28MixedVirtuallyDiamondDerived8_21MixedVirtuallyDerived: 13u エントリ 0 18446744073709551608u 8 (整数 (*)(...))0 16 (int (*)(...))(& _ZTI21MixedVirtuallyDerived) 24 0u 32 0u 40 (整数 (*)(...))OtherBase::g 48 0u 56 8u 64 (整数 (*)(...))8 72 (int (*)(...))(& _ZTI21MixedVirtuallyDerived) 80 0u 88 0u 96 (整数 (*)(...))__cxa_pure_virtual MixedVirtuallyDiamondDerived の VTT MixedVirtuallyDiamondDerived::_ZTT28MixedVirtuallyDiamondDerived: 7u エントリ 0 ((& MixedVirtuallyDiamondDerived::_ZTV28MixedVirtuallyDiamondDerived) + 40u) 8 ((& MixedVirtuallyDiamondDerived::_ZTC28MixedVirtuallyDiamondDerived0_16VirtuallyDerived) + 40u) 16 ((& MixedVirtuallyDiamondDerived::_ZTC28MixedVirtuallyDiamondDerived0_16VirtuallyDerived) + 40u) 24 ((& MixedVirtuallyDiamondDerived::_ZTC28MixedVirtuallyDiamondDerived8_21MixedVirtuallyDerived) + 24u) 32 ((& MixedVirtuallyDiamondDerived::_ZTC28MixedVirtuallyDiamondDerived8_21MixedVirtuallyDerived) + 80u) 40 ((& MixedVirtuallyDiamondDerived::_ZTV28MixedVirtuallyDiamondDerived) + 40u) 48 ((& MixedVirtuallyDiamondDerived::_ZTV28MixedVirtuallyDiamondDerived) + 96u) クラス MixedVirtuallyDiamondDerived サイズ=16 整列=8 base size=16 base align=8 MixedVirtuallyDiamondDerived (0x0x7fd42c0b5310) 0 vptridx=0u vptr=((& MixedVirtuallyDiamondDerived::_ZTV28MixedVirtuallyDiamondDerived) + 40u) VirtuallyDerived (0x0x7fd42c02d750) 0 ほとんど空 プライマリ-MixedVirtuallyDiamondDerived 用 (0x0x7fd42c0b5310) subvttidx=8u ベース (0x0x7fd42c035d20) 0 ほぼ空の仮想 primary-for VirtuallyDerived (0x0x7fd42c02d750) vptridx=40u vbaseoffset=-40 MixedVirtuallyDerived (0x0x7fd42c0b5380) 8 ほとんど空 subvttidx=24u vptridx=48u vptr=((& MixedVirtuallyDiamondDerived::_ZTV28MixedVirtuallyDiamondDerived) + 96u) ベース (0x0x7fd42c035d20) 代替パス OtherBase (0x0x7fd42c035d80) 8 ほとんど空 プライマリ-MixedVirtuallyDerived 用 (0x0x7fd42c0b5380) VirtuallyMultiplyDerived の Vtable VirtuallyMultiplyDerived::_ZTV24VirtuallyMultiplyDerived: 16u エントリ 0 8u 8 0u 16 0u 24 0u 32 (整数 (*)(...))0 40 (int (*)(...))(& _ZTI24VirtuallyMultiplyDerived) 48 0u 56 0u 64 (整数 (*)(...))__cxa_pure_virtual 72 0u 80 18446744073709551608u 88 (整数 (*)(...))-8 96 (int (*)(...))(& _ZTI24VirtuallyMultiplyDerived) 104 0u 112 0u 120 (整数 (*)(...))OtherBase::g VirtuallyMultiplyDerived の VTT VirtuallyMultiplyDerived::_ZTT24VirtuallyMultiplyDerived: 3u エントリ 0 ((& VirtuallyMultiplyDerived::_ZTV24VirtuallyMultiplyDerived) + 48u) 8 ((& VirtuallyMultiplyDerived::_ZTV24VirtuallyMultiplyDerived) + 48u) 16 ((& VirtuallyMultiplyDerived::_ZTV24VirtuallyMultiplyDerived) + 104u) クラス VirtuallyMultiplyDerived サイズ=16 整列=8 ベースサイズ=8 ベースアライン=8 VirtuallyMultiplyDerived (0x0x7fd42c0b59a0) 0 ほぼ空 vptridx=0u vptr=((& VirtuallyMultiplyDerived::_ZTV24VirtuallyMultiplyDerived) + 48u) ベース (0x0x7fd42c035e40) 0 ほぼ空の仮想 プライマリ - VirtuallyMultiplyDerived 用 (0x0x7fd42c0b59a0) vptridx=8u vbaseoffset=-40 OtherBase (0x0x7fd42c035ea0) 8 ほぼ空の仮想 vptridx=16u vbaseoffset=-48 vptr=((& VirtuallyMultiplyDerived::_ZTV24VirtuallyMultiplyDerived) + 104u) OtherVirtuallyMultiplyDerived の Vtable OtherVirtuallyMultiplyDerived::_ZTV29OtherVirtuallyMultiplyDerived: 16u エントリ 0 8u 8 0u 16 0u 24 0u 32 (整数 (*)(...))0 40 (int (*)(...))(& _ZTI29OtherVirtuallyMultiplyDerived) 48 0u 56 0u 64 (整数 (*)(...))__cxa_pure_virtual 72 0u 80 18446744073709551608u 88 (整数 (*)(...))-8 96 (int (*)(...))(& _ZTI29OtherVirtuallyMultiplyDerived) 104 0u 112 0u 120 (整数 (*)(...))OtherBase::g OtherVirtuallyMultiplyDerived の VTT OtherVirtuallyMultiplyDerived::_ZTT29OtherVirtuallyMultiplyDerived: 3u エントリ 0 ((& OtherVirtuallyMultiplyDerived::_ZTV29OtherVirtuallyMultiplyDerived) + 48u) 8 ((& OtherVirtuallyMultiplyDerived::_ZTV29OtherVirtuallyMultiplyDerived) + 48u) 16 ((& OtherVirtuallyMultiplyDerived::_ZTV29OtherVirtuallyMultiplyDerived) + 104u) クラス OtherVirtuallyMultiplyDerived サイズ=16 整列=8 ベースサイズ=8 ベースアライン=8 OtherVirtuallyMultiplyDerived (0x0x7fd42c0b5d90) 0 ほぼ空 vptridx=0u vptr=((& OtherVirtuallyMultiplyDerived::_ZTV29OtherVirtuallyMultiplyDerived) + 48u) ベース (0x0x7fd42c035f00) 0 ほぼ空の仮想 primary-for OtherVirtuallyMultiplyDerived (0x0x7fd42c0b5d90) vptridx=8u vbaseoffset=-40 OtherBase (0x0x7fd42c035f60) 8 ほぼ空の仮想 vptridx=16u vbaseoffset=-48 vptr=((& OtherVirtuallyMultiplyDerived::_ZTV29OtherVirtuallyMultiplyDerived) + 104u) MultiplyVirtuallyDiamondDerived の Vtable MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived: 26u エントリ 0 16u 8 0u 16 0u 24 0u 32 (整数 (*)(...))0 40 (int (*)(...))(& _ZTI31MultiplyVirtuallyDiamondDerived) 48 (int (*)(...))MultiplyVirtuallyDiamondDerived::~MultiplyVirtuallyDiamondDerived 56 (int (*)(...))MultiplyVirtuallyDiamondDerived::~MultiplyVirtuallyDiamondDerived 64 (int (*)(...))MultiplyVirtuallyDiamondDerived::f 72 (int (*)(...))MultiplyVirtuallyDiamondDerived::g 80 8u 88 18446744073709551608u 96 18446744073709551608u 104 18446744073709551608u 112 (整数 (*)(...))-8 120 (int (*)(...))(& _ZTI31MultiplyVirtuallyDiamondDerived) 128 (int (*)(...))MultiplyVirtuallyDiamondDerived::_ZThn8_N31MultiplyVirtuallyDiamondDerivedD1Ev 136 (int (*)(...))MultiplyVirtuallyDiamondDerived::_ZThn8_N31MultiplyVirtuallyDiamondDerivedD0Ev 144 0u 152 18446744073709551600u 160 18446744073709551600u 168 (整数 (*)(...))-16 176 (int (*)(...))(& _ZTI31MultiplyVirtuallyDiamondDerived) 184 (int (*)(...))MultiplyVirtuallyDiamondDerived::_ZTv0_n24_N31MultiplyVirtuallyDiamondDerivedD1Ev 192 (int (*)(...))MultiplyVirtuallyDiamondDerived::_ZTv0_n24_N31MultiplyVirtuallyDiamondDerivedD0Ev 200 (int (*)(...))MultiplyVirtuallyDiamondDerived::_ZTv0_n32_N31MultiplyVirtuallyDiamondDerived1gEv MultiplyVirtuallyDiamondDerived の VirtuallyMultiplyDerived (0x0x7fd42bcdf230 インスタンス) の構築 vtable MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived0_24VirtuallyMultiplyDerived: 16u エントリ 0 16u 8 0u 16 0u 24 0u 32 (整数 (*)(...))0 40 (int (*)(...))(& _ZTI24VirtuallyMultiplyDerived) 48 0u 56 0u 64 (整数 (*)(...))__cxa_pure_virtual 72 0u 80 18446744073709551600u 88 (整数 (*)(...))-16 96 (int (*)(...))(& _ZTI24VirtuallyMultiplyDerived) 104 0u 112 0u 120 (整数 (*)(...))OtherBase::g MultiplyVirtuallyDiamondDerived の OtherVirtuallyMultiplyDerived (0x0x7fd42bcdf2a0 インスタンス) の構築 vtable MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived8_29OtherVirtuallyMultiplyDerived: 23u エントリ 0 8u 8 18446744073709551608u 16 18446744073709551608u 24 0u 32 (整数 (*)(...))0 40 (int (*)(...))(& _ZTI29OtherVirtuallyMultiplyDerived) 48 0u 56 0u 64 (整数 (*)(...))__cxa_pure_virtual 72 0u 80 8u 88 (整数 (*)(...))8 96 (int (*)(...))(& _ZTI29OtherVirtuallyMultiplyDerived) 104 0u 112 0u 120 (整数 (*)(...))__cxa_pure_virtual 128 0u 136 18446744073709551608u 144 (整数 (*)(...))-8 152 (int (*)(...))(& _ZTI29OtherVirtuallyMultiplyDerived) 160 0u 168 0u 176 (整数 (*)(...))OtherBase::g MultiplyVirtuallyDiamondDerived の VTT MultiplyVirtuallyDiamondDerived::_ZTT31MultiplyVirtuallyDiamondDerived: 10u エントリ 0 ((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 48u) 8 ((& MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived0_24VirtuallyMultiplyDerived) + 48u) 16 ((& MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived0_24VirtuallyMultiplyDerived) + 48u) 24 ((& MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived0_24VirtuallyMultiplyDerived) + 104u) 32 ((& MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived8_29OtherVirtuallyMultiplyDerived) + 48u) 40 ((& MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived8_29OtherVirtuallyMultiplyDerived) + 104u) 48 ((& MultiplyVirtuallyDiamondDerived::_ZTC31MultiplyVirtuallyDiamondDerived8_29OtherVirtuallyMultiplyDerived) + 160u) 56 ((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 48u) 64 ((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 184u) 72 ((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 128u) クラス MultiplyVirtuallyDiamondDerived サイズ=24 整列=8 base size=16 base align=8 MultiplyVirtuallyDiamondDerived (0x0x7fd42bcdf1c0) 0 vptridx=0u vptr=((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 48u) VirtuallyMultiplyDerived (0x0x7fd42bcdf230) 0 ほぼ空 プライマリ-MultiplyVirtuallyDiamondDerived (0x0x7fd42bcdf1c0) の場合 subvttidx=8u ベース (0x0x7fd42bce2000) 0 ほぼ空の仮想 プライマリ - VirtuallyMultiplyDerived 用 (0x0x7fd42bcdf230) vptridx=56u vbaseoffset=-40 OtherBase (0x0x7fd42bce2060) 16 ほぼ空の仮想 vptridx=64u vbaseoffset=-48 vptr=((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 184u) OtherVirtuallyMultiplyDerived (0x0x7fd42bcdf2a0) 8 ほぼ空 失われたプライマリ subvttidx=32u vptridx=72u vptr=((& MultiplyVirtuallyDiamondDerived::_ZTV31MultiplyVirtuallyDiamondDerived) + 128u) ベース (0x0x7fd42bce2000) 代替パス OtherBase (0x0x7fd42bce2060) 代替パス
私が見たコンパイラの実装のほとんどは、基本オブジェクトを派生オブジェクトに「埋め込む」だけです。オブジェクトへの相対オフセットは、コンパイル時に参照が評価されるときに追加されるだけなので、vtable が保持される場所は無関係になります。
多重継承と仮想継承はより複雑で、アクセス対象に応じて異なるオフセットが必要になる場合があります。
Code Project: The Impossively Fast C++ Delegatesに関するこの記事を読むことを強くお勧めします。
さまざまなコンパイラが継承のさまざまな側面をどのように処理するかについて、全体像を見事に示しています。さまざまなコンパイラの低レベルの動作に興味がある場合は、ぜひお読みください。
編集:そこに間違った記事をリンクしました。訂正しました。