32 : Make sure public inheritance models "is-a."


0 引言 Inheritance and Object-Oriented Design

从这一章开始,我们将阅读到有关程序设计的条款。

如果你之前是其他程序的编写者,要做好对C++特色OOP与众不同的准备。你将对OOP的概念产生变化。

1 public继承和is-a之间的等价关系

1.1 is-a的字面含义

子类对象 即 是一个 父类对象

derived class object IS A base class object

1.2 面向结构体系无法完全保证is-a法则

考虑以下代码:

void eat( const Person& p );
void study( const Student& s );
Person p;
Student s; eat( p ); // OK
eat( s ); // OK
study( s ); //OK
study( p ); // ERR 人不一定是学生,但你又无法阻止用户这么去做。

而在面向对象中,你可以通过继承关系来扩大缩小对象的行为个数。   之后的矩形与正方形的关系也与该例类似。

1.3 一些“鸟事”

考虑以下继承关系:

class Bird {
public:
virtual void fly(); // 鸟可以飞
...
};
class Penguin : public Bird { // 企鹅是一种鸟
...
};

突然之间我们遇见了乱流,企鹅确实是一种鸟,但他不能飞。

在这个例子中,我们成了不严谨语言(英语)的牺牲品。我们一般说的鸟会飞是指一部分鸟会飞,而相当一部分鸟是不会飞的。

修改成如下继承关系。

class Bird { ... };
class FlyingBird : public Bird {
public:
virtual void fly();
...
};
class Penguin : public Bird {
...
};

但如果你的重点不在鸟会不会飞的时候,这样做显得冗余,这时下第一种情况显得更加合乎完美一些。

另一种想法
void error( const std::string& msg );
class Penguin : public Bird {
public:
virtual void fly() { error( "Attempt to make a penguin fly!" ) } // 运行时错误
};
或是
class Bird {
...
};
class Penguin : public Bird {
...
};
Penguin p;
p.fly(); // 编译时错误

好的接口可以防止无效的代码通过编译(条款18),因此宁可采取第二种方法也不要使用“只在运行时期才能侦测他们”的设计。

请记住

”public继承“意味着is-a。适用于父类身上的每一件事情也一定也适用于子类,因为每一个子类对象也都是一个父类对象。

专业词汇


is-a
has-a
is-implemented-in-terms-of

Effective C++ 笔记:条款 32 确定你的public继承塑造出正确的is-a关系的更多相关文章

  1. 条款32:确定你的public继承塑模出is-a的关系

    Make sure public inheritance models "is –a " 如果令clsss D 以public的形式继承class B,你便是告诉编译器说,每一个类 ...

  2. [Effective JavaScript 笔记]第32条:始终不要修改__proto__属性

    __proto__属性很特殊,它提供了Object.getPrototypeOf方法所不具备的额外能力,即修改对象原型链接的能力. 避免修改__proto__属性的最明显的原因是可移植性的问题.并不是 ...

  3. Effective C++ Item 32 确保你的 public 继承模子里出来 is-a 关联

    本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:"public继承"意味 is-a.适用于 base classe ...

  4. EC读书笔记系列之15:条款32、33、34

    条款32 确保你的public继承塑模出is-a关系 记住: ★public继承意味着is-a.适用于base class身上的每一件事情一定也适用于derived class身上,∵每一个deriv ...

  5. Effective C++笔记 55条编程法则

    1.  视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2.  尽量以const,enum.inline替代#define 1) 对于单纯常量,最好以const ...

  6. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  7. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  8. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  9. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

随机推荐

  1. 查找二叉树(tree_a)

    问题 E: 查找二叉树(tree_a) 时间限制: 1 Sec  内存限制: 128 MB提交: 206  解决: 152[提交][状态][讨论版][命题人:quanxing][Edit] [Test ...

  2. [转]检测到有潜在危险的 Request.Form 值

    <system.web> <httpRuntime targetFramework="4.0" requestValidationMode="2.0&q ...

  3. 微信小程序如何设置服务器配置

    最近微信小程序在it界火了起来,公司也要求我们开始接触微信小程序,废话不多说直接从配置微信小程序开始 1,首先,登录 https://mp.weixin.qq.com,(这里默认你已经获取到微信小程序 ...

  4. Pycharm2018的激活方法或破解方法(必须加host)

    修改hosts文件将0.0.0.0 account.jetbrains.com添加到hosts文件最后,注意hosts文件无后缀,如果遇到无法修改或权限问题,可以采用覆盖的方法去替换hosts文件 修 ...

  5. html/css/js-layer弹出层的初次使用

    学习前端有时很多时候要用到弹出层,原生的js写有些麻烦,而且不美观,基于jQuery的弹出层组件layer应运而生,近些年来备受青睐.官网上有使用教程,但当初用的时候还是糊里糊涂,今天来记录一下lay ...

  6. WebService上传下载图片

    WebService服务端 接受要上传的图片 public string UploadImg(byte[] fileBytes, int id) { try { string filePath = M ...

  7. centos7安装elasticsearch6.3.x集群并破解安装x-pack

    一.环境信息及安装前准备 主机角色(内存不要小于1G): 软件及版本(百度网盘链接地址和密码:链接: https://pan.baidu.com/s/17bYc8MRw54GWCQCXR6pKjg 提 ...

  8. SpringMVC - 运行流程图及原理分析

    流程示意图: 代码分析图:

  9. jvm常见的面试题

    1. 内存模型以及分区,需要详细到每个区放什么. 2. 堆里面的分区:Eden,survival from to,老年代,各自的特点. 3. 对象创建方法,对象的内存分配,对象的访问定位. 4. GC ...

  10. wireshark抓本地回环包

    问题描述: 在网络程序开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以 方法一:Wi ...