Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在虚拟基类子对象之前是什么?_C++ - Fatal编程技术网

C++ 在虚拟基类子对象之前是什么?

C++ 在虚拟基类子对象之前是什么?,c++,C++,我的代码是: 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

我的代码是:

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 D\n"); }
    __declspec(noinline) virtual ~D() { printf("dtor in D\n"); }
};

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, %d\n", &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 D\n"); }
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)  
; ...
删除pd;
00161D01 mov eax,dword ptr[edi+4]
00161D04 lea ecx,[edi+4]
00161D07 mov eax,dword ptr[eax+4]
00161D0A添加ecx、eax
00161D0C推送1
00161D0E mov eax,德沃德ptr[ecx]
00161D10呼叫dword ptr[eax+8]
00161D13 pop edi
; 呼叫删除在这里进行

00161D20子ecx,dword ptr[ecx-4] 是的!使用
#pragma vtordisp(off)
来避免它

假设这是
D
本身的vptr?我不这么认为,到
D
的vptr设置为
00161AED mov dword ptr[edx],1633F0h
,并且vptr不能为0(另外:)“减的值正是到虚拟基类子对象的偏移量。”--您回答了自己的问题。我建议您只需找到ABI的规范,而不是对代码进行反向工程。。。