如何通过c ++编译器在内存中实现虚拟继承?

Ami*_*ira 4 c++ visual-c++ c++11

我对VIRTUAL关键字感到困惑.我试图找到编译器如何在内存中实现它.好的,让我用例子解释一下.我使用Microsoft Visual Studio 2010作为虚拟的实现取决于编译器.

这是第一个代码

#include<iostream>
class one
{
    int _a;
public:
    virtual ~one(){}
};
class two:public one
{
    int _a;
public:
    virtual ~two(){}
};

int main()
{
    using namespace std;
    cout<<"sizeof two="<<sizeof(two)<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

o/p是12个字节,因为_ vptr _two,一个:: _ a和两个:: _ a

这是另一个示例代码

#include<iostream>
class one
{
    int _a;
public:
    virtual ~one(){}
};
class two
{
    int _a;
public:
    virtual ~two(){}
};
class three:virtual public one,virtual public two
{
};

int main()
{
    using namespace std;
    cout<<"sizeof three="<<sizeof(three)<<endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,o/p是20个字节:O,怎么样?请解释!!根据我,它应该是16个字节.__vptr_three(指向vtable的指针),_ vptr1_three(指向虚拟基类表的指针),一个:: _ a和两个:: _ a.为什么要维护虚拟基类表?

51k*_*51k 7

这个pdf包含了编译器的编写者需要了解的一切,VC++中如何实现虚拟继承.

下面是构造函数的反汇编class three,

00A516BD  cmp         dword ptr [ebp+8],0 
00A516C1  je          three::three+60h (0A516F0h) 
00A516C3  mov         eax,dword ptr [this] 
00A516C6  mov         dword ptr [eax],offset three::`vbtable' (0A57828h) => 4 Bytes
00A516CC  mov         ecx,dword ptr [this] 
00A516CF  add         ecx,8 
00A516D2  call        one::one (0A51253h) 
00A516D7  or          dword ptr [ebp-0D4h],1 
00A516DE  mov         ecx,dword ptr [this] 
00A516E1  add         ecx,10h 
00A516E4  call        two::two (0A512BCh) 
00A516E9  or          dword ptr [ebp-0D4h],2 
00A516F0  mov         eax,dword ptr [this] 
00A516F3  mov         ecx,dword ptr [eax] 
00A516F5  mov         edx,dword ptr [ecx+4] 
00A516F8  mov         eax,dword ptr [this] 
00A516FB  mov         dword ptr [eax+edx],offset three::`vftable' (0A57820h)  => 4 Bytes
00A51702  mov         eax,dword ptr [this] 
00A51705  mov         ecx,dword ptr [eax] 
00A51707  mov         edx,dword ptr [ecx+8] 
00A5170A  mov         eax,dword ptr [this] 
00A5170D  mov         dword ptr [eax+edx],offset three::`vftable' (0A57814h)   => 4 Bytes
00A51714  mov         eax,dword ptr [this] 
00A51717  pop         edi  
00A51718  pop         esi  
00A51719  pop         ebx  
00A5171A  add         esp,0D8h 
Run Code Online (Sandbox Code Playgroud)

如上所示,
虚拟基表指针占用4个字节,(vbtable)
2个虚函数表指针占用4*2 = 8个字节,(vftable)
该成员one::_a占用4个字节
该成员two::_a占用4个字节

因此在所有20个字节中.2个虚函数表指针的原因在pdf(第17页)中给出,如下所示,

"在Visual C++中,为了避免在获取vftable条目时对虚拟基础P进行昂贵的转换,T的新虚拟函数在新的vftable中接收条目,需要在T的顶部引入新的vfptr"

  • 我想,如果这个pdf将被删除,你应该从pdf中添加一些段落到答案. (4认同)