
25.多继承
25.1 多继承的概念
C++中一个类可以从多个基类中派生(即可以有多个父类),这就是多继承。
简单的多继承方式是:派生类有两个或以上的基类,基类之间没有什么关系。

上图定义了两个基类BaseA和BaseB,然后再定义一个派生类Derive,让这个类公开继承两个基类。

运行程序结果显示程序先调用了BaseA的构造函数,然后调用了BaseB的构造函数,最后又调用了派生类的构造函数。
多继承下的派生类会拥有所有基类中的数据和函数。如果基类中的成员是是用protected标记的,那派生类可以直接访问这些成员。
复杂的多继承方式是:派生类的基类之间有继承关系。

上图中的B类和C类分别派生自A类,然后又定义一个派生自B类和C类的D类,由于B类和C类有共同的基类A,所以继承关系变得复杂了。

25.2 多继承带来的问题
上面的例子运行后,结果如下图:

我们会发现在实例化一个D类的对象时,基类A的构造函数被调用了2次,B类和C类的构造函数分别被调用了1次。这就会产生一个问题:D类的对象同时包含两个了2个A类的对。这是怎么回事呢?然而问题还没有结束,在尝试想通过D类的对象设置price的值时,会发现函数调用报错了。

原来B类和C类都继承自A类,两个类中都有price属性,也都有setPrice()和getPrice()函数,在D类中使用这些属性和方法时,系统不确定你想调用的是D的哪个父类的成员函数。所以通过d对象调用setPrice()和getPrice()函数时会歧义的,称为多继承函数调用的“二义性”。
如何解决二义性的问题?如下图可以使用完全限定名(即加上类的作用域)的方式。

25.3 虚继承
在构造一个D类的对象时,A类被构造了两次,也就是说D的对象中含有两个A类对象,这是不合理的。因为D类的对象只需要一个基类的对象就够了,所以在多继承中引入虚继承的概念可以解决这个问题。

上图中让B类和C类虚继承A类,只要在继承中使用virtual关键字就可以。重新修改D的构造函数实现,把参数递给A类的构造函数。

这样再次运行程序,结果显示A的构造函数只被调用了1次。
在程序设计中最好不要出现多继承,如果需要多继承时,可以把类的继承关系设计为一个基类和多个只包含功能作为接口的抽象类。
| 留言与评论(共有 0 条评论) |