复合(composition)是类型之间的一种关系,考虑如下代码:
class Address { }; // 住址
class PhoneNumber {};
class Person {
private:
std::string name;
Address address;
PhoneNumber voiceNumber;
PhoneNumber faxNumber;
};
Person
对象是由string
,Address
,PhoneNumber
构成;上述Person class
示范has-a
关系,Person
有一个名称,一个地址,以及语音和传真两笔电话号码;
比较麻烦的是区分is-a
(是一种)和is-implemented-in-terms-of
(根据某物实现出)的关系,假如你需要一个template
,希望制造出一组classes用来表现由不重复对象组成的sets
,你的实现如下:
template<typename T> //将list用于Set是错误做法
class Set : public std::list<T> {};
如条框32所说:如果D是一种B,对B为真的每一件事情对D也都应该为真,但是list
可以内含重复元素,如果数值3051被安插到list<int>
两次,那个list
将内含两笔3051;Set
不可以内含重复元素,如果数值3051被安插到Set<int>
两次,这个set
只内含一笔3051;因此"Set是一种list
"并不为真,因为对list
对象为真的某些事情对Set
对象并不为真;
由于这个两个classes
(Set
和list
)之间并非is-a关系,所以public
继承不适合用来塑模它们;正确的做法是了解,Set
对象可根据一个list
对象实现出来
template<class T> // 将list应用与Set,正确做法
class Set {
public:
bool member(const T &item) const;
bool insert(const T &item);
void remove(const T &item);
std::size_t size() cosnt;
private:
std::list<T> rep; //用来表述Set的数据
};