Effective C++:条款38:通过复合塑模出has-a或“根据某物实现出”

(一)

public继承是“is-a“的关系,而复合有”has-a“或”根据某物实现出(is-implemented-in-terms-of)“的意思——当复合发生在应用域内的对象之间,表现出has-a关系;当它发生于实现域内则是表示“根据某物实现出”的关系。

应用域部分,相当于你塑造的世界中的某些事物,例如人,汽车等。

后者的对象则是实现细节人工产品(这产品现实世界中是没有的),像什么mutex,list,container等等。这些对象是你的软件的实现领域。

复合:

class Address{...};
class PhoneNumber{...};
class Person{
      ...
private:
      std::string name_;
      Address address_;
      PhoneNumber voiceNumber_;
      PhoneNumber faxNumber_;
};

(二)

实例:set的构造。标准程序库中有set模板,它“每个元素都耗用三个指针”,是用平衡查找树实现而成,使它们在查找、插入、删除元素时保证拥有log(n)的效率。

可能会想到像这样实现:

让set继承stl::list:

template<typename T>
class Set : public list<T>{...};   //将list应用于set。错误做法。

这种做法是错误的!因为:public继承是is-a关系,父类能做的,子类也一定能做。但set不是一种list,因为对list为真的某些事情对set对象并不为真。例如,list可以内含重复元素,如果30被安插到list<int>两次,那个list将内含两个30,如果30被安插到set<int>两次,set只内含一个30.

所以这两个classes之间并非is-a关系。不应该是public继承,正确的做法是,set对象可根据一个list对象实现出来:

template <typename T>
class Set {
public:
	bool member(const T& item) const;
	void insert(const T& item);
	void remove(const T& item);
	size_t size() const;
private:
	list<T> rep;
};

template <typename T>
bool Set<T>::member(const T& item) const {
	return find(rep.begin(), rep.end(), item) != rep.end();
}

template <typename T>
void Set<T>::insert(const T& item) {
	if(!member(item)) rep.push_back(item);
}

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

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

请记住:

(1)复合的意义和public继承完全不同。

(2)在应用域,复合意味着has-a(有一个)。在实现域,复合意味着is-implemented-in-terms-of(根据某物实现出)。

Effective C++:条款38:通过复合塑模出has-a或“根据某物实现出”,布布扣,bubuko.com

时间: 2024-10-12 20:38:03

Effective C++:条款38:通过复合塑模出has-a或“根据某物实现出”的相关文章

Effective C++ 条款38 通过复合塑模出has-a或&quot;根据某物实现出&quot;

1. public继承体现is-a关系,要求接口的完全继承,而复合体现has-a或"根据某物实现出"的关系. 当复合发生在应用域(世界中的某些事物,如人,汽车,一张剪辑视频画面等)内的对象之间,表现出has-a关系,当发生在实现域(细节上的人工制品,如缓冲区,互斥器,查找树等)内,表现出is-implementation-in-terms-of(根据某物实现出)的关系. 2. 对于is-implementation-in-terms-of,例如基于list实现set(当空间比时间更重要

Effective C++ Item 38 通过复合塑模出 has-a 或 is-implemented-in-terms-of

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:在应用域,复合意味着 has-a. 在实现域,复合意味着 is-implemented-in-terms-of 示例: template<typename T> //将list应用于 Set.错误做法 class Set: public std::list<T> {...}; 解析: public 继承表示 is-a,即如果D是一种B,对B为真的每一件事,对D也应该为真

条款38:通过复合塑模has-a或“根据某物实现出”

NOTE: 1.复合(composition)的意义和public继承完全不同. 2.在应用域(application domain),复合意味 has-a(有一个). 在实现域(implementation domain),复合意味is-implemented-in-terms-of(根据某物实现出),

Effective C++ 条款38

本节条款相对简单,通俗的意思就是说 "有一个"和"是一个"的区别,以及在应用域(application domain)和实现域之间的区别(implementation domain). 如下代码: 1. class Bird//鸟 { public: //............ }; class ostrich:public Bird//鸵鸟 { public: //............ }; 这段代码是指"是一个"的关系,鸵鸟也是鸟,鸵鸟

Effective C++:条款32:确定你的public继承塑模出is-a关系

(一) public继承意味着"is-a"关系.它的意思是:如果B以public形式继承自A,那么B类型对象肯定是一个A对象,反之不成立.A是B的一种抽象,B是A的特例.任何使用A的地方,都能使用B. (二) public继承意味着"is a"(是一种)关系: (1)任何一个继承类对象也是一个基类对象: (2)任何可以出现基类对象的地方也可以出现一个继承类对象(例如函数的实参): (3)任何一个可以在基类对象上所做的操作,同样也可以在派生类上操作(结果可能是设计者想

《Effective C++》之条款32:确定你的public继承塑模出is-a关系

<Effective C++> 条款32:确定你的public继承塑模出is-a关系 Public inheritance(公开继承)意味"is-a"的关系. 例子如下: class Person{ ... }; class Student : public Person{ ... }; void eat(const Person& p);//任何人都会吃 void study(const Student& s);//只有学生才到校学习 Person p;/

Effective C++ Item 32 确定你的 public 继承塑模出 is-a 关系

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:"public继承"意味 is-a.适用于 base classes 身上的每一件事情一定也适用于 derived classes 身上, 因为每一个 derived classes 身上,因为每一个 derived class 对象也都是一个 base class 对象. 示例: class Person {...}; class Student: public Pers

effective c++条款32~40“继承与面向对象设计”整理

条款32:确定你的public继承塑模出is-a关系 以C++进行面向对象编程,最重要的一个规则是:public inheritance(公有继承)意味is-a(是一种)的关系. 在C++领域中,任何函数如果期望获得一个类型为基类的实参(而不管是传指针或是引用),都也愿意接受一个派生类对象(而不管是传指针或是引用).(只对public继承才成立.)好的接口可以防止无效的代码通过编译,因此你应该宁可采取"在编译期拒绝"的设计,而不是"运行期才侦测"的设计.is a并不

Effective C++ 条款39 明智而审慎地使用private继承

1. public继承表明is-a的关系,要求接口的完全继承,而private继承表明"根据某物实现出的关系",要求仅仅继承实现,private继承有两个规则: 1). 经由private继承而来的基类的所有成员在派生类中都会变成private属性 2). 由于1),编译器不允许将派生类转为基类以防止对派生类private成员的非法访问. 2. 由条款38,private继承和复合具有相同作用——"根据某物实现出".两者之间,要尽可能使用复合,除非必要情况.必要情况