Effective C++ 总结笔记(五)
六、继承与面向对象设计
32.确定你的public继承塑模出is-a关系
public继承意味着is-a。适用于base class身上的每一件事情也一定适用于derived class身上。每一个derived class对象也都是一个base class对象。
33.避免遮掩继承而来的名称
编译器对于各作用域有查找顺序,内层作用域的名称会遮掩外围作用域的名称,所以会造成名称遮掩,各作用域依次为:
global作用域
namespace
base class
derived class
local作用域
等等
1.派生类内的名称会遮掩基类内的名称。
2.可以利用using声明式或者inline转交函数使遮掩函数重见天日
34.区分接口继承和实现继承
1. pure virtual函数使derived class只具体指定接口继承,并且必须被任何继承了它的具象class重新声明。我们也可以为pure virtual函数提供定义,但调用它的唯一途径是指出其class名称。
2. impure virtual函数使derived class继承函数接口以及更平常更安全的缺省实现。
我们可以为impure virtual函数提供定义,派生类可以选择继承函数接口或者一份缺省实现。
3.non-virtual函数使derived class继承函数的接口和一份强制性实现
35.考虑virtual函数以外的其他选择
1.Non-Virtual Interface手法实现Template Method模式:令客户通过public non-virtual成员函数间接调用private virtual函数,得以在一个virtual函数被调用之前设定好场景,并在调用结束之后清理场景。

2.藉由Function Pointers实现Strategy模式:可以由构造函数接受一个指针,指向一个提供该功能的函数,例如:

3.藉由tr1::function完成Strategy模式:改用一个类型为tr1::function的对象,这样的对象可以保存任何可调用物(callable entity,即函数指针、函数对象、成员函数指针),只要其签名式兼容于需求端,上面的typedef语句修改为:
typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc;
接受一个reference指向const GameCharacter,并返回int。
4.古典的Strategy模式:将继承体系内的virtual函数替换为另一个继承体系内的virtual函数,如下:

只要为HealthCalcFunc继承体系添加一个derived class就行了。
36.绝不重新定义继承而来的non-virtual函数
non-virtual函数是静态绑定的,virtual函数是动态绑定的
37.绝不重新定义继承而来的缺省参数值
原因:virtual函数是动态绑定的,但缺省参数值却是静态绑定,可能会在调用一个定义于derived class内的virtual函数时,使用base class指定的缺省参数值。
使用NVI手法(令public non-virtual函数调用private virtual函数)可以防止缺省参数值被重新定义
注:
为了运行期效率,c++坚持缺省参数值为静态绑定,防止运行期复杂的决定
38.通过复合塑模出has-a或根据某物实现出

- 复合和public继承的意义完全不同
- 复合发生于应用域内的对象之间,意味has-a(有一个)的关系;当它发生于实现域内则是表现is-implemented-in-terms-of(根据某物实现出)的关系。
39.明智而审慎地使用private继承
Private继承的规则:如果classes之间的继承关系是private,编译器不会自动将一个derived class对象转换为一个base class对象。
1.Private继承意味implemented-in-terms-of(只有实现被继承,接口部分应略去)
2.尽可能使用复合,必要时才使用private继承(当derived class想访问base class的protected成分时,或为了重新定义virtual函数时,还有造成EBO(empty base optimization)节省内存时才为必要)
*40*.明智而审慎的使用多重继承
1.多重继承可能从多个base class继承相同名称,可能导致“菱形继承”(base class被多次构造,可以使用virtual继承解决)
2.使用virtual继承导致对象体积大,访问成员变量速度慢等问题;因此,非必要不要使用virtual bases,如果要使用,尽可能避免在其中放置数据(相当于对virtual继承)
3.多重继承的一个正当用途是“复合+继承”技术,单一继承更受欢迎
Effective C++ 总结笔记(五)的更多相关文章
- Effective STL 读书笔记
Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- 《MFC游戏开发》笔记五 定时器和简单动画
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9332377 作者:七十一雾央 新浪微博:http:// ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- Crazyflie笔记五: CRTP 实时通信协议(一)(转)
源:Crazyflie笔记五: CRTP 实时通信协议(一) 这里详细介绍了 Crazyflie 的 CRTP实时通信协议的相关内容,由于内容很长,分几篇博文来讲述.这里是第一节内容.欢迎交流:301 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- Django开发笔记五
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.页面继承 定义base.html: <!DOC ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
随机推荐
- Java8通过Function获取字段名(获取实体类的字段名称)
看似很鸡肋其实在某些特殊场景还是比较有用的.比如你将实体类转Map或者拿到一个Map结果的时候,你是怎么获取某个map的key和value.方法一:声明 String key1="name& ...
- spring-data-redis 上百万的 QPS 压力太大连接失败,我 TM 人傻了
大家好,我们最近业务量暴涨,导致我最近一直 TM 人傻了.前几天晚上,发现由于业务压力激增,某个核心微服务新扩容起来的几个实例,在不同程度上,出现了 Redis 连接失败的异常: org.spring ...
- 从零入门 Serverless | 在线应用的 Serverless 实践
作者 | 唐慧芬(黛忻) 阿里云产品专家 导读:毫无疑问,Serverless 能够在效率和成本上给用户带来巨大收益.那具体到落地又应该怎么做呢?本文就给大家详细解读 Serverless 的落地实践 ...
- Java初步学习——2021.10.10每日总结,第五周周日
(1)今天做了什么: (2)明天准备做什么? (3)遇到的问题,如何解决? 今天继续学习菜鸟教程java字符串实例 5.字符串反转--reverse方法 public class Main { pub ...
- CF850E Random Elections 题解
题目传送门 题目大意 没法描述,过于繁杂. 思路 果然自己是个菜鸡,只能靠读题解读题,难受极了,其实不是很难自己应该做得出来的....哎.... 不难发现可以统计 \(A\) 获胜的情况乘上 \(3\ ...
- gin 源码阅读(5) - 灵活的返回值处理
gin 源码阅读系列文章列表: gin 源码阅读(1) - gin 与 net/http 的关系 gin 源码阅读(2) - http请求是如何流入gin的? gin 源码阅读(3) - gin 路由 ...
- 北航OO第三单元总结
JML基础梳理及工具链 JML的全称是Java Modeling language,即Java建模语言.JML是一种行为接口规格.它为严格的程序设计提供了一套行之有效的方法.通过JML不仅可以基于规格 ...
- (一)、Docker 简介
1.Docker镜像是什么? 镜像是一种轻量级.可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码.运行时.库.环境变量和配置文件. 2.Do ...
- 单片机STM32学习笔记之寄存器映射详解
我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射,那什么叫寄存器映射?寄存器到底是什么? 在存储器Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共32bit,每一 ...
- opencv学习(一)——图像入门
图像入门 一.读取图像 在opencv中使用cv.imread(filename, flags)函数读取图像.filename参数表示读取图像的路径.读取图像的路径应完整给出,且不能含有中文,否则在调 ...