多重继承的优缺点

多重继承的优点很明显:简单,清晰,更有利于复用。不会因为基类一个小小的改变而大张旗鼓去改代码。

 

 

缺点也很明显:首先,二义性。两个基类中有同名方法的时候,你不得不在子类的调用中指明此方法出自那个基类。这看起来有些麻烦,幸好在你迷糊的时候,编译器会提醒你。其次:假如类A派生了B和C,而B和C共同派生了D,麻烦就出现了。这种中间大两头小的继承树有个形象的名字:钻石型继承树(DOD:Diamond Of Death)。从名字看此君绝非善类,事实也如此,A是D的父类没错,但是有两条路径。这样的数据组织方式会有一些难以预料的后果。除去二义性不说,想想吧,D中有多少个看似重复的方法,有多少个名字相同的数据成员!

不惜一切代价,避免DOD的出现。除非,你认为DOD出现在这里是最恰当不过的,而且,确保你你使用了虚基类(虚继承),确保你对每个类的细节都完全清楚,确保你知道虚基类(虚继承)的副作用。

 

其次,多重继承还会带来一些其他的问题:使用父类指针指向子类对象变成了一件复杂的事情。你不得不用到C++中提供的dynamic_cast来执行强制转换。至于dynamic_cast,也是个麻烦的家伙,它是在运行期间而非编译期间进行转换的(因为编译期间它不能确定到底要转向一个什么类型),因此除了会带来一些轻微的性能损失,它要求编译器允许RTTI(Runtime Type Information,运行时类型信息),也就是要求编译器保存所有类在运行时的信息。

 

再者,多重继承还会使得子类的vtable变得不同寻常。单继承的vtable只是在父类vtable的表尾加上新的虚函数,子类对象的vtable中包含了有序的父类vtable。而对于多重继承,两个父类可能有完全不同的vtable,因此,子类的vtable中绝对不可能包含完整的有序的两个父类的vtable。子类的vtable中可能包含了两块不相连的父类vtable,因此每个父类都被迫追加了一个vtable,也就是,每个父类的对象都添加了一个指针。

孰优孰劣,自己把握。没有永远最好的,只有当前适合的。Java中摒弃了多重继承可能也是出于太过复杂,可能有不可料知的结果的原因。

不要随意使用多重继承。大多数的情况,用容器(也就是类的组合法)会更好些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
虚继承是C++中用于解决菱形继承问题的一种机制。通过使用虚继承,可以避免菱形继承带来的数据冗余和二义性问题。下面是虚继承的优点和缺点: 优点: 1. 数据冗余问题解决:虚继承可以确保在派生类中只有一份共同基类的成员,避免了菱形继承中数据冗余的问题。共同基类的成员在派生类中只保存一份,节省了内存空间。 2. 二义性问题解决:虚继承可以消除菱形继承中成员函数调用的二义性问题。通过虚继承,派生类可以明确指定调用哪个父类的成员函数,避免了编译器无法确定调用的困惑。 3. 灵活性和可维护性:虚继承使得多重继承更加灵活。如果一个派生类需要同时具有多个父类的特性,而这些父类又有共同基类,使用虚继承可以更清晰地表示对象之间的关系,提高了代码的可读性和可维护性。 缺点: 1. 运行效率降低:由于虚继承引入了虚函数表和虚指针,会增加内存开销和运行时的额外开销,导致运行效率有所降低。虚继承需要在运行时进行额外的查找和跳转,相比于普通的继承方式,会带来一定的性能损失。 2. 设计复杂性增加:虚继承引入了更复杂的继承关系,需要更谨慎地设计类的层次结构。如果过度使用虚继承,可能会导致继承关系变得混乱和难以理解。 综上所述,虚继承可以解决菱形继承带来的数据冗余和二义性问题,提高代码的可读性和可维护性。然而,它也会带来一定的运行效率降低和设计复杂性增加的问题。在使用虚继承时,需要根据具体情况权衡利弊,并进行合理的设计和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值