继承_多重继承
大约 2 分钟
继承_多重继承
多重继承(multipleinheritance,MI)
使用
- 用逗号分隔,如
class A: public APerent1, public APerent2 {...}
- 用逗号分隔,如
多重继承带来的问题
多重继承比单继承麻烦,也更容易出现问题
多重继承会带来新的问题,其中两个主要问题:
- 从两个不同的基类继承同名方法。解决方案:作用域解析运算符
- 从两个或更多相关基类中继承同一个类的多个实例。解决方案:虚基类
而虚基类该解决方案有会带来新的问题: - 构造时重复传参或无法传参 - 派生类无法调用虚基类的方法
为了解决这些问题需要一些新规则和不同语法
【缺陷补丁】
【缺陷补丁】虚基类——解决多个类同祖先问题
使用
虚基类(virtual base class)与禁止传参给基类原则
- 原理
- 虚基类使得从多个类(他们的基类相同)派生出的对象只继承同一个基类对象(是基类对象而不是基类)
- 即只有一个基类对象副本
- 即新类如果多重继承这些类,也只会有一个基类对象
- 特性
- 禁止信息通过中间类传给基类
- 因为如果继承多个由虚基类派生而来的类,构造基类时重复传参将出错
- 这时需要新的写法——直接调用基类的基类的构造函数
- 虚基类必须使用该新写法,而非虚基类,该写法是非法的
- 写法
- 例:
class A : virtual public APerent {...}
- 或:
class A : public virtual Aperent {...}
(virtual
和public
的次序无关紧要)
- 例:
- 多重继承的写法
- 虚基类为避免重复传参的冲突,禁止信息通过中间类自动传递给基类,而需要显式地调用所需基类的构造函数
- 如:
A() : APerentPerent(), APerent1(), APerent2() {...}
(补注:默认为私有继承)
带来新的问题
虚基类会带来新的问题
重复传参问题(内置问题)解决方案(内置方案):进制信息通过中间量传给基类 ——> 无法传参的问题
- 无法传参问题
- 解决方案:显示调用所需的基类的构造函数
效率和成本
虚基类不是默认的方式,因为其有额外的开销(就像虚函数不是默认的方式那样)
- 在一些情况下,可能需要基类的多个拷贝
- 将基类作为虚基类需要额外的计算
- 这样做有缺点
【缺陷解决】作用域解析运算符——解决基类同名函数问题
- 解决方法
- 方法一:使用作用域解析运算符,如
a.APerent2::fn();
- 方法二:重新定义方法,并指出要使用哪个基类版本的方法,如
void a:fn(){APerent2::fn();}
- 方法一:使用作用域解析运算符,如