C++ 明智而审慎地使用多重继承

20180327 C++ 明智而审慎地使用多重继承


当多重继承(multiple inheritance,MI)运用到程序设计中时,程序有可能从一个以上的基类继承相同的名称(如函数,typedef等),那会导致较多的歧义,eg:
class BorrowableItem{//图书馆允许你借某些东西
public:
  void checkOut();//离开时进行检查
  ...
};


class Company{
private:
  bool checkOut() const;//进公司检查
  ...
};


class MP3Player:
  public BorrowableItem,
  public Company
  {...};


MP3Player mp;
mp.checkOut();//歧义,到底调用的是哪个checkOut() ?




为了解决这个歧义,必须明白指出要调用的哪一个基类内的函数:


mp.BorrowableItem::checkOut();


当然也可以尝试明确调用Company()::checkOut(),但会获得“尝试调用私有成员函数”的错误。


多重继承的意思是 继承一个以上的基类,但这些基类常拥有更改机的基类,这很可能导致“钻石型多重继承”:
class File{...};
class InputFile:public File{...};
class OutputFile:public File{...};
class IOFile:public InPutFile,
             public OutputFile
{...};




假设File类有个成员变量filename,那么IOFile内该有多少比这个名称的数据呢,  C++缺省做法是IOFile从其每一个基类继承一份,所以其对象内有两份filename成员变量。
如果你不想那样做(即它继承自两个基类,而File那么不被复制),你需让带有此数据的类(即File)成为一个虚基类,所以要让所有直接继承自它的类采用“虚继承”:
class File{...};
class InputFile:virtual public File{...};
class OutputFile:virtual public File{...};
class IOFile:public InputFile,
             public OutputFile
{...};






对虚基类(virtual base classes)(同样使用于虚继承)的忠告:
1)非必要不要使用虚基类(virtual base classes),平常请使用非虚(non-virtual)继承;
2)若必须使用虚基类(virtual base classes),尽量避免在其中放置数据。这样你就不需担心这些类身上的初始化(和赋值)所带来的诡异事情。






考虑下面这个用来形容(塑模,Modeling)人的C++ 接口类(Interface class);
class IPerson{
public:
  virtual ~IPerson();
  virtual std::string name() const = 0;
  virtual std::string birthDate() const = 0;  
};




IPerson的客户必须以IPerson的指针(pointers)和引用(references)来编写程序,因为抽象类无法被实体化创建对象,为了创建一些可被当做IPerson来使用的对象,IPerson的客户使用 工厂函数(factory functions)将“派生自IPerson的具象类”实体化:


//factory function(工厂函数),根据一个独一无二的数据库ID创建一个Person对象。
std::tr1::shared_ptr<IPerson> makePerson(DatabaseID personIdentifier);


//这个函数从使用者手上取得一个数据库ID
DatabaseID askUserForDatabaseID();


DatabaseID id(askUserForDatabaseID());
std::tr1::shared_ptr<IPerson> pp(makePerson(id));
                                //创建一个对象支持IPerson接口。
                                //借由IPerson成员函数处理*pp
...










/***********************看的一头雾水***************************/






注意:
1)多重继承比单一继承复杂,它可能导致新的歧义性,以及对虚继承的需要。
2)虚继承会增加大小、速度、初始化(及赋值)复杂度等成本。若虚基类不带任何数据,将是最具实用价值的情况。
3)多重继承的确有正当用途。其中一个用途可以适用到下面的情景: “公有继承摸个接口类(Interface class)”与“私有继承某个协助实现的类”的组合形式。































































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值