C++编程品评系列 担任的本质
当前位置:以往代写 > C/C++ 教程 >C++编程品评系列 担任的本质
2019-06-13

C++编程品评系列 担任的本质

C++编程品评系列 担任的本质

Eiffel和C++都提供了多担任的机制。但Java却没有,因为它认为多担任会导致很多问题的呈现。不外Java提供了接口(interface)作为一种替换机制,它雷同于Objective C中的协议(protocol)。Sun宣称接口可以提供多担任所能提供的所有特性。

Sun所宣称的“多担任会带来很多的问题”这个概念是对的,尤其是在C++顶用以实现多担任的要领更能说明这一点。那些看起来好像利用多担任会比单担任更简朴的来由,此刻都以被证明是毫无意义。譬喻,如何制订对付从两个类之上担任获得的具有沟通名字的数据项之间的计策?它们之间是否兼容?假如是的话,那他们是否应该被归并成为一个实体?假如不兼容,那应该如何区分它们?……这样的列表可以列出很长很长。

Java的接口机制也可以用以实现多担任,但它也有一个很重要的差异之处(与C++对比):担任中的接口必需是抽象的。由于利用接口并没有任何的实作,这就消除了需要从差异实作之间选择的大概。Java答允在接口中声明具有常数字段。当需要多担任时,他们就归并成为一个实体,这样也就不会导致歧义的发生。可是,当这些常数具有差异的值时,又有什么会产生呢?

由于Java不支持多担任,我们就不行以像在C++和Eiffel中那样利用殽杂(mixin)了。殽杂是一种特性,它可以把从差异的类中获得的差异的非抽象的函数放到一起形成一个新的巨大的类。譬喻,我们大概但愿从差异的源代码中导入一些utility函数。然而,我们也可以通过利用组合而不是担任来到达同样的结果,因此,这也就不会对Java组成一个重要的进攻了。

Eiffel在办理多担任问题时并没有导入一个单独的接口机制。

有些人大概认为,相对付多担任来说,单担任更优雅一些。这是一个很出格的概念。

BETA [Madsen 93]就属于认为“多担任不优雅”的那一种:“Beta中没有多担任,这主要是因为(对付多担任)缺乏一个深刻的理论上的领略,而且当前的(对付多担任的)发起在技能上看来也很是巨大”。他们引用了Flavors(一种可以将类殽杂在一起的语言)为证据。与Madsen对比,Flavors中的多担任与其顺序有关,也就是说,担任自(A,B)和担任自(B,A)是纷歧样的。

Ada95是另一种不支持多担任的语言。Ada95支持单担任,并把它叫做标志范例扩展(tagged type extension)。

别的一些人认为,对付某些非凡模子下的问题,多担任可以提供优雅的解法,因此为之支付的尽力也是值得的。固然上面所列出的关于多担任的问题列表并不完善,它仍然显示:与多担任相关的问题是可以被系统地辨识出来的,而一旦问题被确认,它们也就可以被优雅地办理。当[Sakkinen 92]对付多担任研究达到一个很深的水平后,它就得出了上述界说。

Eiffel中回收的要领是,多担任会激发一些有趣的且有挑战性的问题,然后再优雅地办理它们。措施员所需做的所有抉择都被限制在类的担任子句中。它包罗利用renaming来担保浩瀚从担任中得来的同名特性最终成为具有差异名字的特性,对付担任而来的特性所施展的新的export计策:redefining和undefining,以及用来消除歧义的select。在所有的环境下,编译器城市为我们做好这一切,为了使得语义清晰而不管是选择利用fork或是join,措施员都具有完全的节制权。

C++中相对Eiffel来说有着别的一种差异的用于消除歧义的机制。在Eiffel中,在renames子句中,特性间必需有着差异的名字。在C++中,可以利用域理会操纵符’::’来区分成员。Eiffel的做法长处在于,歧义在声明中就被消除去了。Eiffel的担任子句相对C++的来说要巨大不少,但它的代码也显得更简朴,更稳固,并更具弹性。这也就是声明要领与操纵符要领对比的好地方在。在C++中,每次当我们遇到在多个成员间具有歧义时,我们必需在代码中利用域理会操纵符。这经使得代码变得杂乱不堪,影响其延展性,假如有其他处所的改变会影响歧义时,我们大概就需要在歧义大概呈现的每个处所改变已有的代码。

依照[Stroustrup 94]中12.8节所说,ANSI委员会思量过利用renaming,可是这个提议被委员会中的一个成员所阻塞掉了,他僵持让委员会中的其他成员用两周时间来好好地思量这个问题。在12.8节中给出的例子显示了在没有显示的renaming的前提下,如何做可以获得同样的结果。问题在于,假如这都需要那些专家们利用两周来思量如何实现,那留给我们的空间又有几多呢?

域理会操纵符并不可是被用来消除多担任所带来的歧义。由于设计精采的语言可以制止歧义的呈现,因此域理会操纵符也就是一个丑恶的,加深巨大性的实作手法。

#p#分页标题#e#

在C++中,“如何来声明多担任中的父类们”是一个很巨大的问题。它影响到了建构函数被挪用的序次,当措施员确实想从子类转到父类时也会导致问题的呈现。然而,我们也可以把这个称为欠好的措施设计气势气魄。

C++和Eiffel的另一个差异之处在于直接的反复担任,Eiffel中答允:

class B inherit A, A end 但

class B : public A, public A { };

却不被C++承认。

    关键字:

在线提交作业