c++虚继承的内存问题

转自: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.youkuaiyun.com/onlyonename/article/details/8062756。至于为什么多个虚继承只有一个类指针,人个猜可能是各个虚基类的位置按
书写的继承先后顺序依次存放在vtable中,类指针指向表中第一个书写的虚基类。相关参考文献有http://blog.youkuaiyun.com/onlyonename/article/details/8068871http://blog.youkuaiyun.com/onlyonename/article/details/8068990http://blog.youkuaiyun.com/onlyonename/article/details/7040913http://blog.youkuaiyun.com/onlyonename/article/details/7041115http://blog.youkuaiyun.com/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;		//第一个字节存a
	short b;	//b是两字节, 对齐到两字节处, 第3、4字节存b, 第2字节空白
	int c;		//同理5、6、7、8存c
};

class B
{
	short b;	//第1、2个字节存b
	int 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;	//8
	cout << sizeof(B) << endl;	//12
	cout << sizeof(C) << endl;	//7
	cout << sizeof(D) << endl;	//7
	return 0;
}
追问
怎么有变成内存对齐问题啦 你不是说空类是1 我觉得你的解释有问题存在
你qq是多少 加我了解下 谢谢
回答
class A
{
	char a;		//第一个字节存a
	short b;	//b是两字节, 对齐到两字节处, 第3、4字节存b, 第2字节空白
	int c;		//同理5、6、7、8存c
};
比如这里,char a是一个字节,但是对齐之后占了两个字节。
内存对齐会影响sizeof计算的。具体和编译器的实现有关。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值