Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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+在内存中实现的+;编译程序?_C++_Visual C++_C++11 - Fatal编程技术网

C++ 虚拟继承是如何通过c+在内存中实现的+;编译程序?

C++ 虚拟继承是如何通过c+在内存中实现的+;编译程序?,c++,visual-c++,c++11,C++,Visual C++,C++11,我被虚拟关键词弄糊涂了。我试图找出编译器是如何在内存中实现这一点的。 好的,让我举例说明。我使用MicrosoftVisualStudio2010作为虚拟依赖编译器的实现 这是第一个代码 #include<iostream> class one { int _a; public: virtual ~one(){} }; class two:public one { int _a; public: virtual ~two(){} }; int mai

我被虚拟关键词弄糊涂了。我试图找出编译器是如何在内存中实现这一点的。 好的,让我举例说明。我使用MicrosoftVisualStudio2010作为虚拟依赖编译器的实现

这是第一个代码

#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;
}
#包括
一班
{
国际组织;
公众:
虚拟~one(){}
};
第二类:公共一级
{
国际组织;
公众:
虚拟~two(){}
};
int main()
{
使用名称空间std;
cout这包含了您需要了解的所有内容,虚拟继承是如何由编译器的编写者在VC++中实现的

下面是
第三类
构造函数的反汇编

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 
如上所示,
虚拟基表指针占用4个字节,(vbtable)
2虚拟函数表指针取4*2=8字节,(vftable)
成员
one::_a
需要4个字节
成员
two::_a
需要4个字节

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


Visual C++中,为了避免在获取VFTABLE条目时对虚拟基础P的昂贵转换,T的新虚函数,在新的VFTABLE中接收新的VFPTR,在T.

< P>的顶部引入,这完全是具体实现的,编译器可以自由地按其喜欢的方式组织事物。(并使生成的类任意大小)提供所有功能

从外观上看,我假设类
three
包含三个隐藏指针(系统上每4个字节):一个“虚拟基指针”,包含三个
中虚拟基的地址,一个虚拟函数指针包含一个中虚拟函数的地址,第二个虚拟函数指针包含两个中虚拟函数的地址

指针是3*4字节,加上基类的两个
int
成员是2*4字节,总共是20字节


当然,如果要在64位机器上编译此代码(使用8字节指针),然后你会得到一些不同的结果:至少32字节,但如果编译器决定需要填充
int
成员,可能会更多。

我认为,你应该在答案中添加一些段落,以防删除此pdf。事实上,只链接的答案是不受欢迎的,因为它们倾向于链接腐烂。这很好,而且实际上我鼓励您提供参考资料来补充您的答案;但是,答案的内容应该在堆栈溢出时立即可以访问(如果仅以宽泛的笔划)。如果您解释为什么20…@51k很高兴知道pdf回答了它,请稍候,我在第11页:)!!“正如您在上面看到的”-这应该会很有帮助“正如你在上面清楚看到的"注意:您的虚拟基类示例…很奇怪。理论上,虚拟继承用于解决菱形问题:D继承自C和B,C和B都继承自A。您没有菱形,因此虚拟继承在您的情况下是无用的。@MatthieuM。您的观点与matt相关,但我并没有试图实现我刚刚学习的任何内容:)当你学习时,你应该学习所有方面!!!这也是我所怀疑的,但为什么要使用两个虚拟函数指针??
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