条款40:慎重的选择多重继承

多重继承很容易带来的一个问题就是歧义的问题:

 1 class BorrowAble{
 2 public:
 3     void checkOut() const;
 4     ...
 5 };
 6 class ElectronicGadget{
 7 private:
 8     bool checkOut()const;
 9     ...
10 };
11 class MP3Player:
12     public BorrowAbleItem,
13     public ElectronicGadget
14     {...};
15 MP3Player mp;
16 mp.checkOut();
这样checkOut的调用实际上就是未定义的了,不考虑作用域来说,这个mp能够取得两个checkOut的名称。
可能的调用方法就是:mp.BorrowableItem::checkOut();
 
还有一种致命的问题就是:如果两个base类还拥有一个相同的基类的话,那么就会导致base对象的重复发生。正确的做法是像下面这样使用virtual继承,这样就避免了继承相同的数据:
1 class File{...};
2 class InputFile : virtual public File{...};
3 class OutputFile : virtual public File{...};
4 class IOFile : public InputFile,
5                 public OutputFile
6                 {...};
当然,使用virtual继承是要付出代价的,起生成的对象往往会更大以及访问速度也会变慢。
 
另外一个不太显著的缺点是,通过virtual继承得到的最终类往往与其含有数据的基类距离不止一个的继承距离。但是这些类同时还要负责这些佛如初始化工作。
 
所以综上所述:对于virtual base class 的忠告是很简单的:非必须不要使用virtual base, 如果要使用尽量不要再virtual base中存放数据,以免忘了进行初始化工作之后带来一些诡异的后果。
 
小结:
多重继承比单一继承要复杂,可能会导致新的歧义性,以及起往往还需要virtual继承
virtual继承会增加,大小,速度,初始化,复杂度等成本,最好的virtual base class不应该带有数据。
多重继承的正确用途往往出现在:
pubic继承自某个interface class以及private 继承字某个协助实现的class二者的组合。
posted @ 2015-10-18 17:00  eversliver  阅读(249)  评论(0编辑  收藏  举报