C++菱形继承与虚继承

菱形继承引入的问题

  • 造成公共父类在子对象中存在多个实例

菱形继承的解决

  • 采用虚继承

虚继承的逻辑

  • 被虚继承的类会变成虚基类,虚基类在子类对象中存放在vbtable中,原本应该存储该父类对象的位置,替换为cbptr,vbptr指向vbtable中虚基类实例的位置,保证虚基类在子类对象中只有一个实例的存在
  • 注意:虚基类在子类构造时会被当做子类的直接父类进行构造。需要在子类的初始化列表中初始化虚基类的产生列表

菱形继承

class A
{
public:
	int a;
	int funa()
	{
		cout << "A::funa()" << endl;
	}
};

class B:public A
{
public:
	int b;
	int funb()
	{
		cout << "B::funb()" << endl;
	}
};

class C :public A
{
public:
	int c;
	int func()
	{
		cout << "C::func()" << endl;
	}
};

class D :public B,public C
{
public:
	int d;
	int fund()
	{
		cout << "D::fund()" << endl;
	}
};

int main()
{
	D dd;
	return 0;
}

不合理的地方

  • D对象中会有2个A的作用域
    在这里插入图片描述

在这里插入图片描述

查看类布局的方式:使用命令 cl

步骤1:隐藏头文件
在这里插入图片描述

  • 步骤2:
    2.1打开源文件所在地
    2.2shift+鼠标右键+打开Powershell窗口
    在这里插入图片描述
  • 步骤3:
    输入命令:
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

菱形继承的构造

class A
{
public:

	A(int a)
	{
		_a = a;
		cout << "A::析构" << endl;
	}
	int _a;

	int funa()
	{
		cout << "A::funa()" << endl;
	}
};

class B:public A
{
public:

	B(int a, int b)
		:A(a)
	{
		_b = b;
		cout << "B::析构" << endl;
	}

	int _b;
	int funb()
	{
		cout << "B::funb()" << endl;
	}
};

class C :public A
{
public:

	C(int a, int c)
		:A(a)
	{
		_c = c;
		cout << "C::析构" << endl;
	}

	int _c;
	int func()
	{
		cout << "C::func()" << endl;
	}
};

class D :public B,public C
{
public:

	D(int a1,int a2,int b,int c,int d)
		:B(a1,b),C(a2,c)
	{
		_d = d;
		cout << "D::析构" << endl;
	}

	int _d;
	int fund()
	{
		cout << "D::fund()" << endl;
	}
};

虚继承

  • 继承权限前加了virtual的继承方式称为虚继承
class A
{
public:
	int a;
	int funa()
	{
		cout << "A::funa()" << endl;
	}
};

class B:virtual public A
{
public:
	int b;
	int funb()
	{
		cout << "B::funb()" << endl;
	}
};

class C :virtual public A
{
public:
	int c;
	int func()
	{
		cout << "C::func()" << endl;
	}
};

class D :public B,public C
{
public:
	int d;
	int fund()
	{
		cout << "D::fund()" << endl;
	}
};

int main()
{
	D dd;
	cout << dd.a << endl;
	return 0;
}

虚基类

  • 被虚继承的类称为虚基类

在这里插入图片描述

虚继承构造

在这里插入图片描述
在这里插入图片描述

虚继承的作用

虚基类作为父类在子类中被构造时是被放在vbtable中的。原本该存放该虚基类对象的地方被替换成了vbptr,vbptr就指向vbtable中虚基类对象的位置。此时就保证了在子类对象中只有一份虚基类对象。虚继承最主要的目的就是解决菱形继承带来的调用不明确问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值