多继承(非虚继承)派生类对象内存结构(基类有虚函数)

在多继承中(非虚继承),探索一下派生类对象在内存中怎么分布的。

首先定义多继承 

class Base1{
	public:
	Base1():a(10){} 
	virtual void funBase1()
	{
		cout<<"This is Base1 Class"<<endl;
	}
	int a;
};
class Base2{
	public: 
	Base2():a(20){}
	virtual void funBase2()
	{
		cout<<"This is Base2 Class"<<endl;
	}
	int a;
};
class Derived:public Base1,public Base2{
	public:
	Derived():a(30){} 
	/*
void funBase1()
	{
		cout<<"This is Derived(funBase1) Class"<<endl;
	}
	void funBase2()
	{
		cout<<"This is Derived(Base2) Class"<<endl;
	}*/
	int a;
};
通过sizeof查看一下派生类D所占内存为20个字节。把这20个字节的内容,以4个字节为单位输出。
Derived D;
	cout<<"对象所占内存大小:"<<sizeof(D)<<endl; 
 	int **p=(int **)&D;
 	cout<<"以4字节为单位,分成5部分:"<<endl;
 	for(int i=0; i<5; i++)
 		cout<<"第"<<i<<"个部分的值"<<p[i]<<endl;

输出结果:

对象所占内存大小:20
以4字节为单位,分成5部分:
第0个部分的值0x444080
第1个部分的值0xa
第2个部分的值0x44408c
第3个部分的值0x14
第4个部分的值0x1e

可以看出,第1部分、第3部分、第4部分为类Base1、Base2、Derived中变量a的值。
第0部分和第2部分,看起来像地址,猜想是虚函数表的地址。因为有2个基类Base1和Base2,应该有2个虚函数表。
派生类并没有重新实现虚函数,按照前面的博客,虚函数表中,虚函数地址应该和基类虚函数地址一样,来验证一下

	Derived D;
	Base1 B1;
	Base2 B2; 
	int **p=(int **)&D;
	cout<<"虚函数表1中虚函数地址0x"<<hex<<p[0][0]<<endl;//对应第0部分 
	cout<<"虚函数表2中虚函数地址0x"<<hex<<p[2][0]<<endl;//对应第1部分
 	p=(int **)&B1;
	cout<<"基类Base1虚函数的地址0x"<<hex<<p[0][0]<<endl;
	p=(int **)&B2;
	cout<<"基类Base2虚函数的地址0x"<<hex<<p[0][0]<<endl;

输出结果: 
虚函数表1中虚函数地址0x4153c8
虚函数表2中虚函数地址0x415424
基类Base1虚函数的地址0x4153c8
基类Base2虚函数的地址0x415424 
可以看出派生类虚函数表1中虚函数地址与基类Base1的虚函数地址相同。
派生类虚函数表2中的虚函数地址与基类Base2的虚函数地址相同。
由此可以得出派生类对象在内存中的结构分布:


可以的出结论:
在派生类的基类中,如果基类有虚函数,那么在派生类中会有对应的虚函数表指针。虚函数表指针的位置与基类中成员变量多少有关。
派生类对象内存分布规则是:(假设基类都有虚函数) 
第1基类对应的虚函数表指针
第1基类成员变量
……
第n基类对应的虚函数表指针
第n基类成员变量
派生类自己的成员变量

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值