C++-继承:多重继承 && 虚拟继承

来源:互联网 发布:h5打开淘宝app 编辑:程序博客网 时间:2024/05/16 19:17

1、多重继承

1.1、多重继承的概念

单一继承&多重继承

1.2、多重继承方式下成员名的二义性

在多继承下,派生类继承了多个基类的成员,当两个不同基类拥有同名成员时,容易产生命名冲突的问题。

使用类域限定符明确指出调用函数所属的基类,如m.A::f()。

1.3、多重继承的构造函数和析构函数

派生类必须为每个基类的构造函数提供初始化参数,构造函数的调用次序是先基类,再对象成员,最后才是派生类的构造函数。基类构造函数的调用次序与它们被继承时的声明次序相同,与初始化列表中的次序没有关系。

2、虚拟继承

2.1、虚拟继承引入的原因

C++在解析派生类的成员函数调用时,会现在派生类中查找该函数,若找到就确定该函数是派生类的成员函数;如果没有找到,就在基类中查找该成员函数。单继承时,没影响;但多继承时,会产生二义性。
例如:

class A {};class B:public A {};class C:public A {};class D:public B, public C {};

在类B和类C中有类A的一份拷贝,类D为类B和类C的多重派生,具有这两个类的数据成员和成员函数的一份拷贝。所以类D有类A的两份成员,这样就会在派生类对象的成员解析时产生二义性。尽管可以用所属类来解决,但对一个对象来说有两个不同的函数,容易产生数据不一致。

2.2、虚拟继承的定义方式

利用C++提供的关键字virtual限定继承方式,将公共基类指定为虚基类,就可以是该基类的成员在派生类中只有一份拷贝。

class A {};class B: virtual public A {};class C: virtual public A {};class D:public B, public C {};

通过对公共基类的虚拟继承,派生类只保留了虚基类的一份成员。

2.3、虚拟继承的构造次序

在虚拟继承下,派生类需要在其构造函数的初始化列表中对虚拟基类进行初始化,以实现虚拟基类对象的初始化。但构造函数的调用次序和非虚拟继承不同:
1、先调用虚基类的构造函数,再调用非虚基类的构造函数;
2、若同一继承层次中包含多个虚基类,就按照它们被继承的先后次序调用。如果某个虚基类的构造函数已经在前面被调用了,就不在被调用。
3、若虚基类由非虚基类派生而来,则先调用虚基类的基类构造函数,再调用虚基类的构造函数。

2.4、虚基类由最终派生类初始化

在没有虚拟继承的情况下,每个派生类的构造函数只负责直接基类的初始化。但是在虚拟继承下,虚基类则由派生类的构造函数负责初始化。
若最终的派生类的构造函数没有明确调用虚基类的构造函数,编译器就会尝试调用虚基类不要参数的构造函数(包括无参和缺省参数的构造函数),如果没有找到就会产生编译错误。

0 0