c++虚继承的内存问题

来源:互联网 发布:lol域名可以备案吗 编辑:程序博客网 时间:2024/06/05 07:38

转自:http://zhidao.baidu.com/question/249749363.html


#include<iostream>using namespace std;class A{};class B{};class C:public virtual A,public virtual B{};int main(){ cout<<sizeof(C); return 0;}输出是8#include<iostream>using namespace std;class A{void virtual fun(){}};class B{void virtual fun(){}};class C:public  A,public  B{};int main(){ cout<<sizeof(C); return 0;}输出是 8但是#include<iostream>using namespace std;class A{void virtual fun(){}};class B{void virtual fun(){}};class C:public virtual  A,public virtual  B{};int main(){ cout<<sizeof(C); return 0;}却输出是12 按理应该是16吧 我用的是vc6.0编译器 望高手给我解决这个问题
--------------------------------------------
回答:
sizeof(A) + sizeof(B) + sizeof(class_ptr)class_ptr即类指针,指向virtual说明的虚基类列表注意,这里面存在内存对齐规则第一个代码:sizeof(A) + sizeof(B) + sizeof(class_ptr) = 1 + 1 + 4, 对齐,得到8第二个代码:sizeof(A) + sizeof(B) = sizeof(vptr) + sizeof(vptr) = 4 + 4 = 8,虚函数表指针第三个代码:sizeof(A) + sizeof(B) + sizeof(class_ptr) = 4 + 4 + 4 = 12就是在第二个的基础上多了一个class_ptr,无论多少个类,都只有一个class_ptr指向这一系列的virtual class。(注意,这很关键。类指针,也即虚基指针,vbptr,是一个用来获得虚基类位置离当前类对象位置偏移的指针,自身位置信息在vtable中虚基类位置信息的下一行给出。可参考http://blog.csdn.net/onlyonename/article/details/8062756。至于为什么多个虚继承只有一个类指针,人个猜可能是各个虚基类的位置按
书写的继承先后顺序依次存放在vtable中,类指针指向表中第一个书写的虚基类。相关参考文献有http://blog.csdn.net/onlyonename/article/details/8068871http://blog.csdn.net/onlyonename/article/details/8068990,http://blog.csdn.net/onlyonename/article/details/7040913,http://blog.csdn.net/onlyonename/article/details/7041115,http://blog.csdn.net/onlyonename/article/details/7041255 by orc)

追问

#include<iostream>using namespace std;class A{char c;};class B{};class C:public virtual A,public virtual B{};int main(){ cout<<sizeof(C); return 0;}缺输出是5  这是为什么呢?

回答

这涉及到内存对齐的细节,内存对齐本来就是和编译器的实现相关的,所以我觉得关于内存对齐的问题可以不必深究,明白虚继承的结构和原理就可以了。最终的结果sizeof(A) + sizeof(B) + sizeof(class_ptr),取决于sizeof(A)的计算,sizeof(A)的计算又取决于内存对齐。【关于内存对齐】你看看下面的代码 Visual Studio 2008下的结果,同样的几个变量,位置不同都会导致sizeof不同。#include <iostream>using namespace std;class A{char a;//第一个字节存ashort b;//b是两字节, 对齐到两字节处, 第3、4字节存b, 第2字节空白int c;//同理5、6、7、8存c};class B{short b;//第1、2个字节存bint c;//对齐到4字节 5、6、7、8 存c, 3、4字节空白(对齐长度变成了4)char a;//9字节存a, 10、11、12字节空白};#pragma pack(1)//告诉编译器按1字节对齐class C{char a;short b;int c;};class D{short b;int c;char a;};int main(){cout << sizeof(A) << endl;//8cout << sizeof(B) << endl;//12cout << sizeof(C) << endl;//7cout << sizeof(D) << endl;//7return 0;}

追问

怎么有变成内存对齐问题啦 你不是说空类是1 我觉得你的解释有问题存在你qq是多少 加我了解下 谢谢

回答

class A{char a;//第一个字节存ashort b;//b是两字节, 对齐到两字节处, 第3、4字节存b, 第2字节空白int c;//同理5、6、7、8存c};比如这里,char a是一个字节,但是对齐之后占了两个字节。内存对齐会影响sizeof计算的。具体和编译器的实现有关。


原创粉丝点击