条款40:明智而审慎地使用多继承

c++继承_c++继承默认私有_c++ 对象继承之间转换 dynamic_cast

请记住

观点

C++社群对多重继承(multiple inheritance MI)持有两类观点。

分析与选择多重继承不值得使用

如果多个基类含有相同的函数,那么继承类调用该函数时,C++首先会确认这个函数与哪个基类的函数最为匹配,找出最佳匹配函数后才检验其可取用性。

如果基类的函数有相同的匹配程度,那就没有所谓的最佳匹配。

多重继承可能会引发歧义(ambiguity)行为,调用继承而来的函数时,必须指明调用

// 图书馆可借的内容
class BorrowableItem
{

public:
    // 离开时进行检查
    void CheckOut()
};

// 一个电子小工具
class ElectronicGadget
{

private:
    // 执行自我检查,返回是否测试成功
    bool CheckOut() const
};

// 某些图书馆愿意借出Mp3播放器
class MP3Player :    // 注意这里的多重继承
  public BorrowableItem, 
  public ElectronicGadget 
{...};

MP3Player mp;
// 歧义!mp对象到底调用的是哪个Checkout函数
mp.Checkout();

这里直接调用 Checkout()函数会报错:”MP3Player::CheckOut” is ambiguous

这里有个问题,MP3Player内部如果没有定义CheckOut函数,而ElectronicGadget类中CheckOut函数又是private的,理论上mp3只能调用BorrowableItem类的CheckOut函数

但是实际上直接调用mp.Checkout();系统会报歧义错误,也就是未能找到最佳匹配函数,也就是C++选择最佳匹配函数时,并不考虑函数是public还是private

所以需要指定调用哪个基类的函数:

// 显示指定调用哪个基类的函数
mp.BorrowableItem::CheckOut();

如果此时指定 ElectronicGadget 类的CheckOut函数,这时候就会报函数是 private,不可调用的错误

mp.ElectronicGadget::CheckOut();
// 函数是private,继承类不可访问
function "ElectronicGadget::CheckOut" (declared at line 16) is inaccessible

钻石型多重继承 ——> virtual继承

多重继承会导致base classes有其更高级的base classesc++继承,会导致“钻石型多重继承”

class File {...};
class InputFile: public File {...};
class OutputFile: public File {...};
class IOFile: public InputFile, public OutputFile {...};

c++继承默认私有_c++ 对象继承之间转换 dynamic_cast_c++继承

这种继承体系某个base class和某个derived class之间有一条以上的想通路线,这必须面对的一个问题是:是不是打算让base class内的成员变量经过每一条路径被复制?

如果File 内有个成员变量 fileName,那么 IOFile内该有多少个这个名称的数据呢?

如果File内的某些东西不是自己想要的,就让带有此数据的class成为一个virtual base class

class File {...};
class InputFile: virtual public File {...};
class OutputFile: virtual public File {...};
class IOFile: public InputFile, public OutputFile {...};

c++继承_c++继承默认私有_c++ 对象继承之间转换 dynamic_cast

使用 public virtual 继承可以避免继承得来的成员变量重复

带来的问题是

使用virtual base classes忠告请记住

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

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

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

限时特惠:本站每日持续更新海量展厅资源,一年会员只需29.9元,全站资源免费下载
站长微信:zhanting688