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等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...
随机推荐
- *浅解嵌入式中的BootLoader
本文只作为本人学习过程中的记录及时不时的突发奇想偶记.鄙人菜鸟一只,文中如有错误或疏漏,若读者肯不吝赐教,在下感激零涕.文章一直不断更新中 一.何为Bootloader 在嵌入式系统中,Bootloa ...
- Zookeeper集群节点数量为什么要是奇数个?
无论是公司的生产环境,还是自己搭建的测试环境,Zookeeper集群的节点个数都是奇数个.至于为什么要是奇数个,以前只是模糊的知道是为了满足选举需要,并不知道详细的原因.最近重点学习zookeeper ...
- html5 + thyleaf引擎
偶然与巧合 舞动了蝶翼 谁的心头风起 前赴而后继 万千人追寻 荒漠唯一菩提 似擦肩相遇 或擦肩而去 命运犹如险棋 无数时间线 无数可能性 终于交织向你
- 一个简单的通讯服务框架(大家发表意见一起研究)JAVA版本
最近研究下java语言,根据一般使用的情况,写了个连接通讯服务的框架: 框架结构 C-Manager-S; 把所有通讯内容抽取成三个方法接口:GetData,SetData,带返还的Get; 所有数据 ...
- HashMap与Hashtable
1. 1) Hashtable继承自Dictionary类,HashMap是map接口的一个实现类(继承自AbstractMap抽象类) 2) 在HashMap中,null可以 ...
- 第二章 Java内存区域与内存溢出异常
运行时数据区域: 程序计数器(Program Counter Register):当前线程执行码行号指示器,属于线程私有内存.字节码解释器工作时就是通过调整这个计数器的值来选取下一条需要执行字节码指令 ...
- hive mysql元数据,报错 Specified key was too long; max key length is 767 bytes
Specified key was too long; max key length is 767 bytes 此错误为hive 元数据mysql 字符集编码问题 如 show create tabl ...
- background url base64
各自含义:data: ----获取数据类型名称image/gif; -----指数据类型名称base64 -----指编码模式AAAAA ------指编码以后的结果. background-imag ...
- Delphi中Chrome Chromium、Cef3学习笔记(二)
原文 http://blog.csdn.net/xtfnpgy/article/details/46635739 用Tchromium替换webbrowser 用惯了EmbeddedWB,不想 ...
- MySQL innodb_autoinc_lock_mode 详解
innodb_autoinc_lock_mode这个参数控制着在向有auto_increment 列的表插入数据时,相关锁的行为: 通过对它的设置可以达到性能与安全(主从的数据一致性)的平衡 [0]我 ...