菱形继承中的虚继承

来源:互联网 发布:央视新闻大数据播报 编辑:程序博客网 时间:2024/06/04 18:08

c++中有三种继承方式 :
1. 公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
2. 保护继承(protected)
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
3. 私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
总结:
1.基类的private成员在派生类中时不可见的,如果基类成员不想在类外边直接被访问,但派生类可以访问,可以定义为protect,可见,protect是为继承准备的。
2.public继承保持is-a的原则,即一个子类就是一个父类,private/protect继承保持has-a的原则,基类的成员并非完全成为子类的一部分。
3.class的默认继承方式为private,struct默认继承方式为public。
4.在实际中,一般使用public继承,很少使用private/protect。
继承是面向对象复用的重要手段,派生类的默认成员函数为合成的,例如在调用派生类的构造函数时,先调用基类的构造函数,在调用派生类的构造函数,如果基类定义了带形参的构造函数,派生类必须定义构造函数
多继承:一个类有两个或两个以上的父类时称继承关系为多继承。
这里写图片描述
菱形继承:
这里写图片描述

class A{int _a;}class B : public A{int _b;}class C : public A{int _c;}class D : public B , public C{int _d;}

上述菱形继承的对象模型为:
这里写图片描述
在D对象中有两个_a,就存在数据冗余和二义性问题,而在实际问题中,往往所期待的是D对象中只有一份_a并且不管改变B中的_a还是C中的_a,D中的_a都会发生改变。因此,引入了虚继承,虚继承下的对象模型为:

这里写图片描述
当B和C需要调用A时,调用的是同一份数据,D对象中只保留一份数据,解决了菱形继承数据冗余和二义性的问题,但也给内存的存放与寻找带来了麻烦,同时伴随着需要空间的增大与时间的延长,用这样会降低程序的效率,所以一般不使用菱形继承。

原创粉丝点击