600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 《Effective C++》读书笔记 条款40:明智而审慎地使用多重继承

《Effective C++》读书笔记 条款40:明智而审慎地使用多重继承

时间:2022-12-08 21:53:45

相关推荐

《Effective C++》读书笔记 条款40:明智而审慎地使用多重继承

多重继承的存在有其合理性,但是在使用多重继承的时候也要注意存在的问题

1.一个派生类可能从多个基类继承相同的名称(函数、typedef等等),这会导致较多的歧义

例子:

#include<iostream>using namespace std;class base1{public:void fun1();void fun2();};class base2{public:void fun1();void fun3();};class Derived :public base1, public base2{};int main(){Derived d;//d.fun1(); //error C2385 : 对“fun1”的访问不明确// 可能是“fun1”(位于基“base1”中)// 也可能是“fun1”(位于基“base2”中)return 0;}

Derived public继承自base1和base2,由于两个基类中存在同名的函数fun1,所以在调用fun1时就出现了歧义,不知道调用的是哪一个,我们可以这样调用

d.base1::fun1();

所以多重继承可能会导致歧义,就算base的fun1()改为private,也不能阻止这种错误。因为C++首先是确认函数的最佳匹配而后才检验其可取性。在基类调用时发现两个相同匹配程度的函数,产生歧义。

2.多重继承导致菱形继承问题

如果B,C继承自A,D又继承自B,C(都是public继承),如上图,

#include<iostream>using namespace std;class A{public:void fun();private:int b;};class B:public A{private:int b1;};class C :public A{private:int b2;};class D :public B, public C{};int main(){D d;d.fun(); //error C2385 : 对“fun”的访问不明确//可能是“fun”(位于基“A”中)// 也可能是“fun”(位于基“A”中)return 0;}

运行胆码会发现调用fun函数产生歧义,错误信息是两个一模一样的fun位于基A中,原因是这种继承导致D从B和C中继承了A,解决办法就是让B和C virtual public继承自A,这虽然可以解决D中存在两份A的问题。

class B:virtual public A{private:int b1;};class C :virtual public A{private:int b2;};class D :public B, public C{};

但是virtual继承会增加对象的体积,是成员访问速度变慢等等,并且virtual 基类的初始化由继承体系中的最底层负责,这里A的初始化由D负责。

尽量不要使用虚基类,如果必须使用,不要在虚基类中放置数据。

多重继承也有其存在的合理性,用public继承接口,用private继承协助实现,这种多重继承的组合书上写了一个例子。所以说多重继承可以使用但是要明智而审慎地使用它

请记住:

1.多重继承比单一继承复杂。它可能导致新的歧义性,以及对virtual继承的需要。

2.virtual继承会增加大小、速度、初始化(及赋值)复杂度等等成本。如果virtual base classes 不带任何数据,将是最具有实用价值的情况。

3.多重继承的确有正当用途。其中一个情节涉及“public继承某个Interface class”和“private继承某个协助实现的class”的两相组合。

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