(一)

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要么“基于一些实现”的更多相关文章

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

    复合(composition)的意义和public继承完全不同. 在应用域(application domain),复合意味has-a(有一个).在实现域(implementation domain) ...

  2. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  3. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  4. [从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)

    前言 今天是进入公司的第三天,为了能尽快投入项目与成为团队可用的战力,我正在努力啃官方文档学习 Angular 的知识,所以这一篇文章主要是记录我如何阅读官方文档后,实现这个非常基本的.带导航的网页应 ...

  5. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  6. Kcptun 是一个非常简单和快速的,基于KCP 协议的UDP 隧道,它可以将TCP 流转换为KCP+UDP 流

    本博客曾经发布了通过 Finalspeed 加速 Shadowsocks 的教程,大家普遍反映能达到一个非常不错的速度.Finalspeed 虽好,就是内存占用稍高,不适合服务器内存本来就小的用户:而 ...

  7. Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分

    1.潜在的自我赋值     a[i] = a[j];     *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象, ...

  8. Effective C++ -----条款25:考虑写出一个不抛异常的swap函数

    当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常. 如果你提供一个member swap,也该提供一个non-member swap用来调用前者.对于cla ...

  9. Effective C++ -----条款12: 复制对象时勿忘其每一个成分

    Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个cop ...

随机推荐

  1. Oracle判断指定列是否全部为数字

    select nvl2(translate(name,'\1234567890 ', '\'),'is   characters ','is   number ') from customer_inf ...

  2. 单元测试工具 SmokeTest

    .NET 程序集单元测试工具 SmokeTest Smoke Test(冒烟测试),也称Regression Test(回归测试),是对软件的安装和基本功能的测试.一般地我们使用脚本来实现Smoke ...

  3. Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)

    原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...

  4. Java中取某一个范围的随机数

    一.取模操作 public static void main(String[] args) { for (int i = 1; i <= 20; i++) { int j = i % 11; S ...

  5. json介绍及简单示例

    JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据 ...

  6. Microsoft JET Database Engine 错误 '80004005'不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

  7. 关于ubuntu下qt编译显示Cannot connect creator comm socket /tmp/qt_temp.xxx/stub-socket的解决的方法

    今天在ubuntu下安装了qtcreator,准备測试一下能否用.果然一測试就出问题了,简单编写后F5编译在gnome-terminal中出现 Cannot connect creator comm ...

  8. POJ 3176:Cow Bowling

    Cow Bowling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13464   Accepted: 8897 Desc ...

  9. 136 - Ugly Numbers

     Ugly Numbers  Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3 ...

  10. VC生成的DLL给QT的EXE调用时lib路径问题小结

    VC生成的DLL给QT调用,有两种方式,一种是隐式调用调用(使用.lib文件方式): ① 在*.pro工程文件中添加VC生成的lib文件路径时,或者使用一个绝对路径,如: LIBS += " ...