虚拟基类子对象之前的内容
what is before the virtual base class subobject?
我的代码是:
class A { /* ... */ };
class B : virtual public A { /* ... */ };
class C : virtual public A { /* ... */ };
class X { /* ... */ };
class Y : virtual public X { /* ... */ };
class Z : virtual public X { /* ... */ };
class D : public B, public C, public Y, public Z {
public:
__declspec(noinline) D() { printf("ctor in Dn"); }
__declspec(noinline) virtual ~D() { printf("dtor in Dn"); }
};
int main()
{
D *pd = new D;
delete pd;
return 0;
}
我发现在虚拟基类子对象之前有4个字节的空间。我不明白他们做什么。
delete pd;
00161D01 mov eax,dword ptr [edi+4]
00161D04 lea ecx,[edi+4]
00161D07 mov eax,dword ptr [eax+4]
00161D0A add ecx,eax
00161D0C push 1
00161D0E mov eax,dword ptr [ecx]
00161D10 call dword ptr [eax+8]
00161D13 pop edi
; call in delete goes here
00161D20 sub ecx,dword ptr [ecx-4] ; <--
00161D23 jmp D::`scalar deleting destructor' (0161C40h)
__declspec(noinline) D() { printf("ctor in D, %dn", &val_); }
00161A80 push ebp
00161A81 mov ebp,esp
00161A83 sub esp,8
00161A86 push ebx
00161A87 push esi
00161A88 mov esi,ecx
00161A8A push edi
00161A8B lea ecx,[esi+28h]
00161A8E mov dword ptr [ebp-8],0
00161A95 mov dword ptr [esi+4],163424h
00161A9C mov dword ptr [esi+0Ch],1633F8h
00161AA3 mov dword ptr [esi+14h],1633F8h
00161AAA mov dword ptr [esi+1Ch],163438h
00161AB1 call A::A (01616B0h)
00161AB6 lea ecx,[esi+30h]
00161AB9 call X::X (01618A0h)
00161ABE push ecx
00161ABF mov ecx,esi
00161AC1 call B::B (0161740h)
00161AC6 push ecx
00161AC7 lea ecx,[esi+8]
00161ACA call C::C (01617F0h)
00161ACF push ecx
00161AD0 lea ecx,[esi+10h]
00161AD3 call Y::Y (0161920h)
00161AD8 push ecx
00161AD9 lea ecx,[esi+18h]
00161ADC call Z::Z (01619D0h)
00161AE1 mov edx,esi
00161AE3 mov dword ptr [esi+8],163394h
00161AEA mov eax,dword ptr [edx+4]
00161AED mov dword ptr [edx],1633F0h
00161AF3 mov dword ptr [esi+10h],16338Ch
00161AFA mov dword ptr [esi+18h],163414h
00161B01 mov eax,dword ptr [eax+4]
00161B04 mov dword ptr [eax+edx+4],163404h
00161B0C mov eax,dword ptr [edx+4]
00161B0F mov eax,dword ptr [eax+8]
00161B12 mov dword ptr [eax+edx+4],1633E4h
00161B1A mov eax,dword ptr [edx+4]
00161B1D mov ecx,dword ptr [eax+4]
00161B20 lea eax,[ecx-24h]
00161B23 mov dword ptr [ecx+edx],eax ; <--
00161B26 mov eax,dword ptr [edx+4]
00161B29 mov ecx,dword ptr [eax+8]
00161B2C lea eax,[ecx-2Ch]
00161B2F mov dword ptr [ecx+edx],eax ; <--
00161B32 lea eax,[edx+20h]
00161B35 push eax
00161B36 push 163318h
00161B3B call dword ptr ds:[16303Ch]
; ...
__declspec(noinline) virtual ~D() { printf("dtor in Dn"); }
00161BB0 push ebx
00161BB1 push esi
00161BB2 push edi
00161BB3 mov edi,ecx
00161BB5 push 163370h
00161BBA mov eax,dword ptr [edi-24h]
00161BBD mov dword ptr [edi-28h],1633F0h
00161BC4 mov dword ptr [edi-20h],163394h
00161BCB mov dword ptr [edi-18h],16338Ch
00161BD2 mov dword ptr [edi-10h],163414h
00161BD9 mov eax,dword ptr [eax+4]
00161BDC mov dword ptr [eax+edi-24h],163404h
00161BE4 mov eax,dword ptr [edi-24h]
00161BE7 mov eax,dword ptr [eax+8]
00161BEA mov dword ptr [eax+edi-24h],1633E4h
00161BF2 mov eax,dword ptr [edi-24h]
00161BF5 mov ecx,dword ptr [eax+4]
00161BF8 lea eax,[ecx-24h]
00161BFB mov dword ptr [ecx+edi-28h],eax ; <--
00161BFF mov eax,dword ptr [edi-24h]
00161C02 mov edx,dword ptr [eax+8]
00161C05 lea eax,[edx-2Ch]
00161C08 mov dword ptr [edx+edi-28h],eax ; <--
00161C0C call dword ptr ds:[16303Ch]
00161C12 add esp,4
00161C15 lea ecx,[edi-8]
00161C18 call Z::~Z (0161A20h)
; ...
在构造函数和析构函数中,值都是0。被减去的值恰好是到虚拟基类子对象的偏移量。
VS2012,发布模式。
它是vtordisp
!使用#pragma vtordisp( off )
以避免
相关文章:
- 按基类对象访问派生类资源时出错
- C++ 构造函数传递对基类对象的引用
- 使用基类对象访问派生的仅类方法
- 如何删除派生类中基类对象的新对象
- 使用基类对象调用Dervied Class函数
- 基类对象是否隐式添加到派生类中?
- 如果我有指向基类对象的指针,如何获取虚拟方法的地址?
- 如何不删除基类对象的副本?
- 如何根据基类对象中的变量值分配派生类中的变量?
- 从基类对象的向量中获取特定派生类的对象
- 您可以将派生的类对象作为函数参数代替基类对象吗?
- 如何使用基类对象设置派生类变量的值
- 通过引用派生类对象从基类对象执行向下转换时引发bad_cast异常
- 如何从现有基类对象创建派生类对象
- 子类对象列表重新解释为基类对象列表?(C++11).
- 派生的类指针使用static_cast指向基类对象
- 对我的基类对象数组使用大量的静态类型转换——这可以吗
- 我怎么知道基类对象的指针数组中元素的类型,它将为派生类分配内存
- 在C++中,为什么编译器不了解基类对象在编译时指向哪个对象?
- 为什么可以从实例化基类对象的投射指针调用非静态派生类方法