Item 40 多重继承

1> 有多重继承,就有可能继承相同的名字:

 

class BorrowableItem { public: void checkOut(); ... }; class ElectronicGadget { private: bool checkOut() const; ... }; class MP3Player : public BorrowableItem , public ElectronicGadget { ... }; // 定义不重要 MP3Player mp; mp.checkOut(); // ambiguous! which checkOut?

 

即使一个公有,一个私有,重名了也不行!C++先找函数,然后才看是否可以访问。

 

2> 有共同的基类,类图就成了环:

 

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

 

那么一个IOFile内有多少个File拷贝?
C++默认是两个File。不过,也可以只有一个:

 

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

 

STL中的多重继承大部分是虚继承。basic_ios、basic_istream、basic_ostream和basic_iostream这四个例外。
从正确性上来看,似乎所有的多重公有继承都应该声明成virtual public。但这样生成的代码大、访问速度慢,虚基类的初始化和赋值的规则更复杂。

建议:
1> 多使用“非虚继承”
2> 非使用“虚继承”不可的时候,尽量不在其中放数据。这就像Java中的interface了。

下面是多重继承的例子:

 

class IPerson { // this class specifies the public: // interface to be implemented virtual ~IPerson(); virtual std::string name() const = 0; virtual std::string birthDate() const = 0; }; class DatabaseID { ... }; // used below; details are unimportant std::tr1::shared_ptr<IPerson> makePerson(DatabaseID personIdentifier) { ... } DatabaseID askUserForDatabaseID() { ... } class PersonInfo { // legacy code; it has functions useful public: // in implementing the IPerson interface explicit PersonInfo(DatabaseID pid); virtual ~PersonInfo(); virtual const char * theName() const; virtual const char * theBirthDate() const; virtual const char * valueDelimOpen() const; virtual const char * valueDelimClose() const; ... }; class CPerson : public IPerson // 继承IPerson使该类能用于makePerson , private PersonInfo // 私有继承这个legacy class,只是为了复用其部分代码 { public: explicit CPerson(DatabaseID pid): PersonInfo(pid) {} //! +--+--+--+--+--+--+--+--+--+--+ //! 用legacy code实现IPerson接口 virtual std::string name() const { return PersonInfo::theName(); } virtual std::string birthDate() const { return PersonInfo::theBirthDate(); } //! +--+--+--+--+--+--+--+--+--+--+ private: //! +--+--+--+--+--+--+--+--+--+--+ //! 重定义那些不合要求的legacy code const char * valueDelimOpen() const { return ""; } const char * valueDelimClose() const { return ""; } //! +--+--+--+--+--+--+--+--+--+--+ }; DatabaseID id(askUserForDatabaseID()); std::tr1::shared_ptr<IPerson> pp(makePerson(id));

你可能感兴趣的:(Item 40 多重继承)