C++多继承之菱形继承原理及解决方法

目录

1.单继承和多继承

2.菱形继承

3.虚继承解决菱形继承

3.1使用方法

3.2虚继承原理

4.继承和组合


1.单继承和多继承

一个子类只有一个父类称为单继承

一个子类有多个父类称为多继承

2.菱形继承

菱形继承是多继承的一种复杂的情况

这里会出现一个问题,Assistant这个类中继承了两个Person类,造成了数据的冗余和二义性

例:

可以通过指定类域解决但是数据的冗余没有解决

3.虚继承解决菱形继承

3.1使用方法

虚继承可以在person被teacher和student继承时使用

在前面加个virtual

3.2虚继承原理

用一个简单的菱形继承模型,在借助内存窗口观察。

class A
{
public:
	int _a;
};
 class B : public A
//class B : virtual public A
{
public:
	int _b;
};
 class C : public A
//class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};
int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}

不加virtual时候看内存窗口很明显D对象中有两个a对象,有数据冗余。

加virtual之后对象A被放在了最底端,之前存放A的位置变成了一个地址。

这个地址指向基虚表,叫做基虚表指针,基虚表中存的时偏移量,通过偏移量可以找到A。

0x01 0F FD A4 + 0x00 00 00 14 = 0x 01 0F FD B8 正好是A的位置。

4.继承和组合

继承是is-a的关系,就是每一个派生类都是一个基类。

组合是has-a的关系,没事派生类都有一个基类

这就是组和

继承是白箱复用,对基类内部可见,一定程度破坏了封装,耦合度高。

组和是黑箱复用,对基类内部不可见,没有破坏封装,耦合度低。

组合比继承的可维护性更高,能用组合的地方就用组合。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++菱形继承是指一个派生类同时继承了两个直接或间接基类,而这两个基类又间接或直接继承自同一个基类,从而形成了一个菱形的继承关系。 例如下面的代码: ``` class A { public: int a; }; class B : public A { public: int b; }; class C : public A { public: int c; }; class D : public B, public C { public: int d; }; ``` 在这个例子中,类 `D` 继承了类 `B` 和类 `C`,而类 `B` 和类 `C` 都继承了类 `A`,因此形成了一个菱形继承关系。 菱形继承会引起一些问题,例如: 1. 内存浪费:由于类 `A` 被重复继承,导致在内存中存在两份相同的 `A` 对象,造成内存浪费。 2. 访问冲突:由于类 `D` 继承了类 `B` 和类 `C`,而这两个类都继承了类 `A`,因此在类 `D` 中访问 `A` 中的成员时会出现访问冲突的问题。 为了解决菱形继承带来的问题,可以使用虚继承。虚继承可以解决内存浪费和访问冲突的问题,它的原理是在派生类中只保留一个虚基类的实例,由所有的派生类共享使用。 修改上面的例子,使用虚继承: ``` class A { public: int a; }; class B : virtual public A { public: int b; }; class C : virtual public A { public: int c; }; class D : public B, public C { public: int d; }; ``` 在这个例子中,类 `B` 和类 `C` 继承类 `A` 时使用了 `virtual` 关键字,表示使用虚继承。这样,类 `D` 中就只有一个 `A` 对象的实例,而且访问 `A` 中的成员也不会出现访问冲突的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值