首页 > 代码库 > Effective C++ Item 40 明智而审慎地使用多重继承

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

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie


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

示例:
class BorrowableItem{
public:
	void checkOut();
};
class ElectronicGadget{
private:
	bool checkOut() const;
};
class MP3Player:
	public BorrowableItem
	public ElectronicGadget
{...};
MP3Player mp;
mp.checkOut()


解析:找出最佳函数后才检验其可取用性。此例中对 checkOut 的调用是歧义的,即使两个函数中只有一个是可取用的(一个 public , 一个 private)
纠正:明确说明调用的是哪一个 base class 内的函数
mp.BorrowableItem::checkOut();

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


经验:多重继承的确有正当用途。其中一个情节涉及“public 继承某个 Interface class”和"private继承某个协助实现的 class"的两相组合。
示例:
class IPerson{ //提供接口
public:
	static std::tr1::shared_ptr<Person> makePerson(DatabaseID personIdentifier);
	virtual ~IPerson();
	virtual std::string name() const = 0;
	virtual std::string birthDate() const = 0;
};


class PersonInfo{ //提供实现
public:
	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, private PersonInfo{
public:
	explicit CPerson(DatabaseID pid): PersonInfo(pid){}
	virtual std::string name() const{ 
		return PersonInfo::theName(); //利用 PersonInfo 的方法实现 IPerson 的接口
	}
	virtual std::string birthDate() const{
		return PersonInfo::theBirthDate();
	}
private:
	const char *valueDelimOpen() const {return "";} //重新定义继承而来的 virtual "界限函数"
	const char *valueDelimClose() const {return "";}
}


DatabaseID askUserForDatabaseID();


DatabaseID id(askUserForDatabaseID());
std::tr1::shared_ptr<IPerson> pp(makePerson(id));