600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Effective C++ 规则40:明智而审慎地使用多重继承

Effective C++ 规则40:明智而审慎地使用多重继承

时间:2022-04-30 21:25:54

相关推荐

Effective C++ 规则40:明智而审慎地使用多重继承

1、多种继承,首先带来一个问题。那就是子类会从多个父类中继承相同的名称。这样,在调用的时候,必然导致歧义。

2、考虑Base1中有个public方法XXX,Base2中有个private方法XXX,Derived继承Base1和Base2,那么分析一下,Derived d; d.XXX()到底调用哪个方法?

你可能会想,虽然两个都匹配,但是只有Base1的XXX方法可访问,因此调用Base1的XXX方法。这种想法是错的,编译报错:对XXX的访问不明确。为什么?

因为编译器决议调用哪个方法的时候,第一步,先把所有匹配的名称都拿来,不管是不是可以访问,然后在里面找到一个最优匹配,如果两个匹配程度一样,编译器就傻眼了,只能报错。经过测试,从多个父类继承相同的名称,即使匹配程度不一样,也会导致对XXX的访问不明确。

怎么解决这个问题呢?

明确告诉编译器,我要调用哪个父类的方法。

d.Base1::XXX(); //OKd.Base2::XXX(); //Error,无法访问成员XXX

注:单一继承也可以使用d.Base1::XXX();这种形式。

3、对于菱形继承(前面的文章有详细的介绍),考虑InputFile继承File,OutputFile继承File,IOFile继承InputFile和OutputFile,File中有个数据fileName,现在出问题了。从继承角度讲,IOFile有两份fileName,但根据常识,IOFile应该只有一个fileName。C++默认的做法是IOFile中有两个fileName。

4、如何解决上面的问题呢?也就是说,保证IOFile中只有一个fileName。通过使用virtual继承。让InputFile和OutputFile使用virtual继承,IOFile的继承方式不变。这样就使得IOFile中,只有一个fileName。显而易见,这种做法非常丑陋。而且,虽然起到了效果,要付出很大的代价。编译器在幕后做了一些事情,导致的结果是:InputFile的体积变大,访问变慢,初始化也可能带来诡异的问题。

5、因此,尽量少使用virtual继承。如果必须使用virtual继承,也要保证不在virtual Base(即File)中放置数据,从而保证IOFile中没有重复的数据。C#和Java中的interface就不允许有数据。相对而言,有重复的方法,还好办,可以指定调用哪个父类的方法。

6、那么,多重继承就一无是处吗?多重继承的使用场景:public继承一个类,暴露接口,同时private继承一个类,根据它来实现。你可能会想,根据某物实现出,不是应该优先使用复合技术吗?private继承可以解决两个问题:一是private继承可以访问protected成员,二是可以重写方法。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。