深度探索c++对象模型-13-单类单继承下的数据成员布局

一、单个类带虚函数的数据成员布局

class MYCLASS
{
public:
	int m_i;
	int m_j;
	virtual void myvirfunc()
	{

	}
	MYCLASS() 
	{
		int abc = 1;
	}

	~MYCLASS()
	{
		int abc = 1;
	}
};
void main()
{
	cout << sizeof(MYCLASS) << endl;
	printf("m_i:%d\n", &MYCLASS::m_i);
	printf("m_j:%d\n", &MYCLASS::m_j);

	system("pause");
}

结果:
在这里插入图片描述
类中引入虚函数时,会有额外的成本付出
1.编译的时候,编译器会产生虚函数表。
2.对象中会产生虚函数表指针vptr,用于指向虚函数表
3.增加或者扩展构造函数,增加给虚函数表指针vptr赋值的代码,让vptr指向虚函数表。
4.如果多重继承,比如你继承了两个父类,每个父类都有虚函数的话,每个父类都会有vptr,那继承时,子类就会把两根vptr都继承过来,如果子类还有自己额外的虚函数的话,子类与第一个基类共用一个vptr.
5.析构函数中也被扩展了虚函数表指针vptr相关的赋值代码,感觉这个赋值代码似乎和构造函数中代码相同。

下面是这个类的布局
在这里插入图片描述
下面是跟踪验证:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以前面的四个字节一定是虚函数表的地址

二、单一继承父类带虚函数的数据成员布局

看代码:

class father
{
public: 
	int m_fi;
	virtual void go(){};
};
class MYCLASS:public father
{
public:
	int m_i;
	int m_j;
	virtual void myvirfunc()
	{

	}
	MYCLASS() 
	{
		int abc = 1;
	}

	~MYCLASS()
	{
		int abc = 1;
	}
};
void main()
{
	cout << sizeof(MYCLASS) << endl;
	printf("m_i:%d\n", &MYCLASS::m_i);
	printf("m_j:%d\n", &MYCLASS::m_j);

	MYCLASS c;
	c.m_i = 1;
	c.m_j = 2;

	system("pause");
}

结果:
在这里插入图片描述
结果为16,因为子类和父类共用一张表,也就是只有一个vptr.由偏移数,可以得到如下布局。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可见往后走了8个字节。

三、单一继承父类不带虚函数的数据成员布局
看如下代码:

class father
{
public: 
	int m_fi;
	
};
class MYCLASS:public father
{
public:
	int m_i;
	int m_j;
	virtual void myvirfunc()
	{

	}
	MYCLASS() 
	{
		int abc = 1;
	}

	~MYCLASS()
	{
		int abc = 1;
	}
};
void main()
{
	cout << sizeof(MYCLASS) << endl;
	printf("m_fi:%d\n", &MYCLASS::m_fi);
	printf("m_i:%d\n", &MYCLASS::m_i);
	printf("m_j:%d\n", &MYCLASS::m_j);

	MYCLASS c;
	c.m_i = 1;
	c.m_j = 2;

	system("pause");
}

结果:
在这里插入图片描述
从偏移结果,可能会得到如下结果(但是是不对的):
在这里插入图片描述

分析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从结果可以得出如下布局图(m_bi就是m_fi)
在这里插入图片描述
那父类带virtual的偏移是4,不带的是0,布局也一样,那是如何访问的呢?
这是由于,当访问父类的m_bi的时候,会将this指针进行调整(+4个字节),这是编译器帮我们做的,加了之后也就是m_bi的地址了。一定要记住偏移只是偏移。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发如雪-ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值