《Effective C++》读书笔记 条款38:通过复合塑模出has-a或“is-implemented-in-terms-of”

复合是类型之间的一种关系,当某种类型的对象内含它种类型的对象,这种关系便是复合。例如下面这段代码,就用到了复合

class Address{ ...... };
class PhoneNumber{ ...... };
class Person{
public:
	...
private:
	std::string name;//合成成分物
	Address address;//同上
	PhoneNumber voiceNumber;//同上
	PhoneNumber faxNumber;//同上
};

区分public继承和复合。public继承是is-a(是一个),复合是has-a(有一个)或is-implemented-in-terms-of(根据某物实现出)。

就如上面这段代码,我们可以说人有一个名字,有一个住址,不能说人是一个名字,人是一个住址。当复合发生在应用域,表现出has-a的关系。程序中的对象相当于你塑造的世界中的某些事物,例如你如这个世界里的人,汽车等,这样的对象(人、汽车)属于应用域,此时我们说世界有人,世界有汽车。例如上面这段代码,name,address,voiceNumber,faxNumber,就是我塑造的人这个类里面的事物,所以这里的复合是应用域,是has-a关系。(其实我觉得可以理解成组成部分吧,一个类的组成部分,属于应用域。就像人这个类由名字、地址、电话号码组成)当复合发生在实现域,表现出is-implemented-in-terms-of关系。那些实现细节的对象属于实现域(大概是为了实现类的某种功能而定义的成员对象属于实现域吧。)

 

来看书上举的例子;用list实现set,最先想到的办法是让Set  public继承list

template <typename T>
class Set:public std::list<T>{......};

这种做法是错误的,因为public继承意味着is-a,也就是Set是一个list,然而,Set是不允许插入重复元素的,你插入两个1,最终的Set中只有一个1,而list不一样,list就会有两个1,list 是可以重复插入相同元素的。那么这种关系就不符合is-a,于是我们就不能利用public继承。考虑复合,根据list对象实现Set对象

template <class T>
class Set
{
public:
	bool member(const T& item) const;
	void insert(const T& item);
	void remove(const T& item);
	std::size_t size() const;
private:
	std::list<T> rep;
};
//检查元素是否有重复的
template < typename T >
bool Set<T>::member(const T& item)const
{
	return std::find(rep.begin(), rep.end, item) != rep.end();
}

//插入元素
template < typename T >
void Set<T>::member(const T& item)
{
	if (!member(item))
		rep.push_back(item);
}

//移除元素
template < typename T >
void Set<T>::remove(const T& item)
{
	typename std::list<T>::iterator it = std::find(rep.begin(), rep.end(), item);
	if (it != rep.end())
		rep.erase(it);
}

//大小
template < typename T >
std::size_t Set<T>::size() const
{
	return rep.size();
}

从上面这段代码可以看出,我们利用list实现了我们的Set,这种关系就是is-implemented-in-terms-of(利根据某物实现出)

 

请记住:

1.复合的意义和public继承完全不同

2.在应用域,复合意味着has-a(有一个)(某类有什么时就是has-a)。在实现域,复合意味着is-implemented-in-terms-of(根据某物实现出)(某类利用其他类对象实现了自己的功能时)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值