c++类对象的内存分布 以及 虚继承实现原理

引子

几个简单类的大小

空类

class Empty {};

int main() {
	cout << sizeof(Empty) << endl; //1
}

空类,1个字节,不表示任何内容。

普通继承

class A {
public:
	int m_A;
	static int s_iA;
	void funA();
};
class B:A {
	short m_B;
	void funB();
};
int main() {
	cout << sizeof(A) << endl; //4
	cout << sizeof(B) << endl;//8,继承m_A4字节,自己的short m_B2字节,对齐变4字节,一共8字节
}

类大小的计算:

  • 只有类成员变量占内存,普通函数不占用内存
  • static变量属于类,不属于对象,也不占用内存

sizeof(A) 4字节,就是int型变量4个字节,static变量不占空间。

sizeof(B) 8个字节,继承类A的int型变量,占用4个字节
自己的short占用两个字节,但是由于内存对齐,short也占用了4字节。
一共8字节。

包含虚函数的继承

class A {
public:
	int m_A;
	static int s_iA;
	virtual void funA();
};
class B:A {
	short m_B;
	void funB();
};
int main() {
	cout << sizeof(A) << endl; //16
	cout << sizeof(B) << endl;//24
}

代码和上面的代码相比,只是在将类A中的函数变成了virtual 。
有虚方法的类对象中会有一个虚指针(vfptr),指向虚表。指针大小取决于操作系统。32位系统指针4字节,64位系统8字节。
即使有多个虚函数,也是写在一张虚表内的,所以只需要一个虚表指针。
这里是64位系统。
sizeof(A) 为16,包含一个虚指针(8字节)+int型变量(4字节,对齐成8字节)。
sizeof(B) 为24,包含一个虚指针(8字节)+继承的int型变量+自己的int型变量。

虚继承

虚继承解决了菱形继承的问题。代码如下

class A {
public:
	int m_A;
	virtual void funA();
};
class B:virtual public A {
	int m_B;
	void funB();
};
class C :virtual public A {
	int m_C;
	void funB();
};
class D :public B, C {
	int m_D;
};
int main() {
	cout << sizeof(A) << endl; //16
	cout << sizeof(B) << endl; //32
	cout << sizeof(C) << endl; //32
	cout << sizeof(D) << endl; //56
}

菱形继承的好处是消除了二义性,减少了内存浪费。
对虚继承的类A,C对象中只会有一份A的数据。
虚继承借助了虚基类表指针(vbptr),在虚继承的类中,虚基类表指针指向了一个偏移量。当前地址加上偏移量就可以得到A数据所在的地址。

sizeof(A) 还是16,这是基类。
sizeof(B)和sizeof©大小相同,都是原来24的大小上加一个vbptr变成了32。
sizeof(D) = sizeof(m_A) //仅一份
+ sizeof(m_B) + sizeof(m_C)
+ sizeof(m_D)
+ sizeof(vbptr)//B虚继承,生成的虚基类指针
+ sizeof(vbptr)//C虚继承,生成的虚基类指针
+ sizeof(vfptr) //指向虚表

参考极大帮助理解~必看!
通过vbptr寻找A成员变量的具体过程
虚继承实现原理,内存示意图

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值