不要被这个诡异的条款名字欺骗了,他说的是一件简单的事情。
而不是用Person去public继承Address,虽然这样做也能让一个人有地址,但是它却违背了public表示is-a的关系。人又不是一个特化了的“地址”。所以,这里使用复合会更恰当一些。复合往往表示2种意思,这取决于你程序的应用:第一种是has-a:当你程序描述的是实际的东西时,大都是这种关系:人有名字,学校有教室等等;第二种是“由XX实现”,比如,集(set)由链表(list)实现等等。
下面就用这个例子来说明:
总之,复合与public继承完全不同,它意味着has-a或者通过XX实现。
比如,定义一个“人”类,而人又有地址,那么你应该这么写:
class Address
{
public:
string country;
string province;
string city;
};
class Person
{
string name;
Address address;
};
而不是用Person去public继承Address,虽然这样做也能让一个人有地址,但是它却违背了public表示is-a的关系。人又不是一个特化了的“地址”。所以,这里使用复合会更恰当一些。复合往往表示2种意思,这取决于你程序的应用:第一种是has-a:当你程序描述的是实际的东西时,大都是这种关系:人有名字,学校有教室等等;第二种是“由XX实现”,比如,集(set)由链表(list)实现等等。
下面就用这个例子来说明:
template<typename T>
class Set
{
public:
bool member(const T& item)const
{
return find(rep.begin(),rep.end(),item) != rep.end();
}
void insert(const T& item)
{
if(!member(item))
rep.push_back(item);
}
void remove(const T& item)
{
typename list<T>::iterator it = find(rep.begin(),rep.end(),item);
if(it != rep.end())
rep.erase(it);
}
size_t size()const
{
return rep.size();
}
void print()
{
list<T>::iterator it = rep.begin();
for(;it != rep.end();++it)
cout<<*it<<"\t"<<endl;
}
private:
list<T> rep;
};
让然,与标准库的set相比,这个例子还是有些瑕疵,因为标准库每次插入元素后,都会自动排序。而这里却不行。
总之,复合与public继承完全不同,它意味着has-a或者通过XX实现。