设为首页 | 加入收藏
您现在的位置: 唯才教育网 >> 电脑频道 >> c/c++ >> MoreExceptionalC++中文版试读(继承与多态)

MoreExceptionalC++中文版试读(继承与多态)

作者:佚名    来源:网友投稿    点击数:    更新时间:

   [Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。]

继承与多态

不来点继承和多态,面向对象将会怎样?

尽管继承常被滥用,但它还是一种很重要的工具——这包括多继承。特别是,当你生活在现实世界中时,你会发现,你经常需要将不同供货商提供的程序库结合起来使用,此时,多继承便凸显它的价值。本章向你展示,在结合使用不同供货商提供的“基于继承”的程序库时,应当如何避免连体双婴(Siamese Twin)问题。此外,本章还示范了许多合理(以及一些不合理地)使用纯虚函数的方式,以及如何编写多继承的替代方案、如何对使用继承关系的用户施加控制。

条款24:为什么要使用多继承?

难度:6

一些语言,包括SQL99标准,还在为“是否应该支持单继承或多继承”的问题大伤脑筋。本条款邀请您讨论这一主题。

1. 什么是多继承(MI,即multiple inheritance)?在C++中引入MI带来了哪些额外的可能性和复杂性?

2. MI究竟有必要吗?如果必要,尽可能多地列举出它的使用场合,并论证为什么应该将MI加入到语言中;如果不必要,请论证为什么单继承(SI)(并且,可能结合Java风格的接口)可以取代多继承、甚至比它更出色,以及为什么不应该将MI加入到语言中。

解答

1. 什么是多继承(MI,即multiple inheritance)?在C++中引入MI带来了哪些额外的可能性和复杂性?


非常简要地回答:MI指的是从多个(多于一个)直接基类(direct class)继承的能力。

例如:

class Derived : public Base1, private Base2

{

//...

};

在C++中引入MI所带来的可能性是:一个类的同一个(直接或间接)基类(base class)可能会不只一次地作为它的基础类(ancestor)出现。这里有一个简单的例子,即那个经典的钻石形状的继承图,如图4所示。

这里,B两次作为D的间接基类(indirect class)出现,一次是通过C1,另一次则是通过C2。

这种情况下,就很有必要引入C++的另一个特性:虚拟继承。现在的问题是:程序员希望D拥有基类B的一个子对象还是两个?如果答案是一个,B就应该是一个虚拟基类,图4就成为了可怕的死亡钻石。如果答案是两个,B就应该是一个普通(非虚拟)基类。

最后,虚拟基类的主要复杂性在于:它们必须通过最底层的派生类(most-derived class)直接初始化。关于这一点的详细介绍,以及MI其它方面的知识,请参阅[stroustrup00],或[Meyers97]条款43。

B

D

C1

C2

MoreExceptionalC++中文版试读(继承与多态)第2部分:


图4可怕的死亡钻石(如果D从B虚拟继承)


设计准则

避免多继承自多个“非protocol类”。(protocol类是一种抽象基类(abstract base class),或简称ABC,它完全由纯虚函数组成,没有数据成员。)

2. MI究竟必要吗?

简短的回答是:只要程序可以用汇编语言(或更低级的语言)来写,就不能说某种特性绝对“必要”。然而,正如大多数人不会去用简单的C编写自己的虚函数机制一样,在某些场合下,没有MI会让你大费周章。

正因为如此,我们现在才有了这一被称为MI的神奇特性。但问题是——或者,至少前面的问题应该换为——MI是个好东西吗?1

简而言之,的确有人认为9 7 3 123 4 8 :

查看和“c/c++”有关的所有文章


  • 上一篇文章:

  • 下一篇文章: