Effective C++ 笔记:条款 32 确定你的public继承塑造出正确的is-a关系
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关系的更多相关文章
- 条款32:确定你的public继承塑模出is-a的关系
Make sure public inheritance models "is –a " 如果令clsss D 以public的形式继承class B,你便是告诉编译器说,每一个类 ...
- [Effective JavaScript 笔记]第32条:始终不要修改__proto__属性
__proto__属性很特殊,它提供了Object.getPrototypeOf方法所不具备的额外能力,即修改对象原型链接的能力. 避免修改__proto__属性的最明显的原因是可移植性的问题.并不是 ...
- Effective C++ Item 32 确保你的 public 继承模子里出来 is-a 关联
本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:"public继承"意味 is-a.适用于 base classe ...
- EC读书笔记系列之15:条款32、33、34
条款32 确保你的public继承塑模出is-a关系 记住: ★public继承意味着is-a.适用于base class身上的每一件事情一定也适用于derived class身上,∵每一个deriv ...
- Effective C++笔记 55条编程法则
1. 视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2. 尽量以const,enum.inline替代#define 1) 对于单纯常量,最好以const ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第3章:使用函数--个人总结
前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...
随机推荐
- 查找二叉树(tree_a)
问题 E: 查找二叉树(tree_a) 时间限制: 1 Sec 内存限制: 128 MB提交: 206 解决: 152[提交][状态][讨论版][命题人:quanxing][Edit] [Test ...
- [转]检测到有潜在危险的 Request.Form 值
<system.web> <httpRuntime targetFramework="4.0" requestValidationMode="2.0&q ...
- 微信小程序如何设置服务器配置
最近微信小程序在it界火了起来,公司也要求我们开始接触微信小程序,废话不多说直接从配置微信小程序开始 1,首先,登录 https://mp.weixin.qq.com,(这里默认你已经获取到微信小程序 ...
- Pycharm2018的激活方法或破解方法(必须加host)
修改hosts文件将0.0.0.0 account.jetbrains.com添加到hosts文件最后,注意hosts文件无后缀,如果遇到无法修改或权限问题,可以采用覆盖的方法去替换hosts文件 修 ...
- html/css/js-layer弹出层的初次使用
学习前端有时很多时候要用到弹出层,原生的js写有些麻烦,而且不美观,基于jQuery的弹出层组件layer应运而生,近些年来备受青睐.官网上有使用教程,但当初用的时候还是糊里糊涂,今天来记录一下lay ...
- WebService上传下载图片
WebService服务端 接受要上传的图片 public string UploadImg(byte[] fileBytes, int id) { try { string filePath = M ...
- centos7安装elasticsearch6.3.x集群并破解安装x-pack
一.环境信息及安装前准备 主机角色(内存不要小于1G): 软件及版本(百度网盘链接地址和密码:链接: https://pan.baidu.com/s/17bYc8MRw54GWCQCXR6pKjg 提 ...
- SpringMVC - 运行流程图及原理分析
流程示意图: 代码分析图:
- jvm常见的面试题
1. 内存模型以及分区,需要详细到每个区放什么. 2. 堆里面的分区:Eden,survival from to,老年代,各自的特点. 3. 对象创建方法,对象的内存分配,对象的访问定位. 4. GC ...
- wireshark抓本地回环包
问题描述: 在网络程序开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以 方法一:Wi ...