虚拟继承,虚函数的详细内存布局二

本文详细探讨了C++中的多重继承情况下,带虚函数时的内存布局,包括非虚继承、单个虚拟继承和全虚拟继承的情况,以及虚函数表的组织和查找机制。
摘要由CSDN通过智能技术生成

测试三:多重继承(带虚函数)

3.1、普通多重继承,带虚函数,自己有新增虚函数

#pragma vtordisp(off)
#include <iostream>

using std::cout;
using std::endl;

class Base1
{
public:
	Base1() : _iBase1(10) {}

	virtual void f()
	{
		cout << "Base1::f()" << endl;
	}

	virtual void g()
	{
		cout << "Base1::g()" << endl;
	}

	virtual void h()
	{
		cout << "Base1::h()" << endl;
	}
private:
	int _iBase1;
};

class Base2
{
public:
	Base2() : _iBase2(100) {}

	virtual void f()
	{
		cout << "Base2::f()" << endl;
	}

	virtual void g()
	{
		cout << "Base2::g()" << endl;
	}

	virtual void h()
	{
		cout << "Base2::h()" << endl;
	}
private:
	int _iBase2;
};

class Base3
{
public:
	Base3() : _iBase3(1000) {}

	virtual void f()
	{
		cout << "Base3::f()" << endl;
	}

	virtual void g()
	{
		cout << "Base3::g()" << endl;
	}

	virtual void h()
	{
		cout << "Base3::h()" << endl;
	}
private:
	int _iBase3;
};


class Derived
	: /*virtual*/ public Base1
	, /*virtual*/ public Base2
	, /*virtual*/ public Base3
{
public:
	Derived() : _iDerived(10000) {}
	void f()
	{
		cout << "Derived::f()" << endl;
	}

	virtual void g1()
	{
		cout << "Derived::g1()" << endl;
	}

private:
	int _iDerived;
};

int main(void)
{
	Derived d;
	return 0;
}

内存布局:

非虚继承,基类的内存布局在前,派生类的在后,自己没有新增虚函数指针,都是继承过来的,新增的虚函数放在继承过来的第一张虚表里,加快查找速度

3.2、虚拟多重继承,带虚函数,自己有新增虚函数(只有第一个是虚继承)

class Derived
	: virtual public Base1
	, /*virtual*/ public Base2
	, /*virtual*/ public Base3
{
public:
	Derived() : _iDerived(10000) {}
	void f()
	{
		cout << "Derived::f()" << endl;
	}

	virtual void g1()
	{
		cout << "Derived::g1()" << endl;
	}

private:
	int _iDerived;
};

内存布局:

虚拟继承,新增一个虚基指针,虚基类的内存布局放在最后

3.3、虚拟多重继承,带虚函数,自己有新增虚函数(三个都是虚继承)

class Derived
	: virtual public Base1
	, virtual public Base2
	, virtual public Base3
{
public:
	Derived() : _iDerived(10000) {}
	void f()
	{
		cout << "Derived::f()" << endl;
	}

	virtual void g1()
	{
		cout << "Derived::g1()" << endl;
	}

private:
	int _iDerived;
};

 内存布局:

总结:

1、不管派生类有没有新增虚函数表,派生类新增的虚函数都放在第一个虚函数表中(可能是继承过来的,也可能是自己新建的,就近原则),加快查找速度

2、派生类会覆盖基类的虚函数,只有第一个从基类继承过来的虚函数表中存放的是真实的被覆盖的虚函数的地址,其它的虚函数表中存放的并不是真实的对应的虚函数的地址,而只是一条跳转指令

3、内存布局:①非虚继承的基类内存布局优先

                        ②派生类内存布局(包括虚基指针和数据成员)在虚基类内存布局之前,通过虚基指针找到虚基类的内存布局,所以虚基类的内存布局放在派生类内存布局之后

4、当继承类型都是虚拟继承时,派生类新增虚函数的话,会新增自己的虚函数指针和虚函数表,新增的虚函数表存放新增虚函数入口地址,位于内存布局的最前面,加快访问速度(时间换空间)

下一篇:虚拟继承,虚函数的详细内存布局三-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值