《Effective C++》阅读总结(四): 设计、声明与实现
第四章: 设计与声明
18. 让接口更容易被正确使用,不易被误用
- 将你的class的public接口设计的符合class所扮演的角色,必要时不仅对传参类型限制,还对传参的值域进一步限制。
19. 设计class犹如设计type
- 内置类型如int、float等,本质也是一个class,用户自定义的class的行为和状态应当与内置类型类似的。设计class时,首先要考虑构造和析构、然后是赋值操作如何实现、考虑class是否要继承某一已有class、尽量使你的class一般化等等需要考虑的问题。
20. 宁以pass-by-reference-to-const
替代pass-by-value
- 这个准则很常见,使用const引用传参以避免拷贝和修改入参。看具体场景,如果是需要修改入参,那么就不要加const、如果入参是简单内置类型,拷贝不怎么消耗资源,那么直接传值也是可以的。同样,使用指针也是一样的道理。此外,传class的引用或指针也可以避免对象切个问题,例如函数接受一个父类对象,当传入子类对象时,父类对象构造函数会被调用,此时子类的属性就会丢失,即切割问题,这是不希望的。
21. 必须返回对象时,不要妄想返回reference
- 很显然的一点就是,你不能返回一个locakl对象的指针或者引用,因为,函数调用结束后,所有存储在栈上的local对象都将被销毁。此外,可以返回在函数内构造的堆对象的指针,但尽量不要返回其引用,引用如果在返回后没有保护好而被覆盖,则造成内存泄漏。
22. 将成员变量声明为private
- 这是一个封装合理的class应当遵守的规则,成员变量声明为private的话,可以通过public接口间接控制成员变量,并加以特殊限制。这样做也有缺点,就是编写代码无法直接修改成员变量,代码量增加。如果只需要保存读取数据,不做其他操作,那么声明一个结构体是一个不错的选择。
我们一把不使用protected成员,没什么用。
23. 宁以non-member
、non-friend
替换member
函数
- 如果一个操作是一般性的,并不是class特有的,那么将其抽离class单独声明定义。
24. 若所有参数都需要类型转换,请为此采用non-member
函数
- 这里的所有参数包括this指针,所以连this指针都需要转换类型,那么这个函数其实就不应该是这个class的成员函数,应当抽离class。
25. 考虑写一个不抛出异常的swap函数
- 使用
std::swap
吧,我觉得目前够用了
第五章 实现
我们写c++代码,一个是如何设计架构,即定义class及其成员函数和成员数据,以及不同class之间的通讯关系;另一个是如何具体实现每个函数,对每个函数或成员函数的功能进行实现,这部分每个功能相对独立,比较底层,但其中也有些需要注意的点,主要有以下几个:
26. 尽可能延后变量定义式的出现时间
- 这样可以提高程序的效率,但我并不认为会提高程序的可读性。对于那些不是非常在意运行效率的函数,可读可维护性要排在效率前面,如初始化,而那些会循环调用很多次的代码,如模型推理计算,效率至上。此外,编译器也会尽可能优化代码,以提高运行时效率。
27. 尽量少做转型动作
C++中的cast方法有四种:
①const_cast
:用于移除对象身上的const属性,只此一个功能。常用。低风险。
②static_cast
:用于强制隐式转换。例如将int转为double,将基类指针转为子类指针时不进行安全检查。不可用于移除const属性。常用。低风险。
③dynamic_cast
:用于执行类继承体系中安全向下转型。也就是用来决定某个对象是否归属类继承体系中的某个类型。比如可以将多态基类(包含虚函数的基类)的指针强制转换为派生类的指针,很耗时,不常用。高风险。
④reinterpret_cast
:用于执行低级转型,例如将int*
转为int
,执行的是逐个比特复制的操作。 不用。高风险。
- 所以,首先尽量避免转型,或者对于不可避免的转型,将转型操作隐藏到函数里面,并且尽量使用C++style的转型方法,不要使用早期C风格的那种方法。在类继承体系中进行上行转换时,
dynamic_cast
和static_cast
效果一样且安全,但下行转换时,dynamic_cast
会进行类型安全检查且耗时,而static_cast
不进行检查。所以如果有必要且明确基类指针是哪个子类时,通常使用static_cast
即可。
移除const属性是危险的,如无十分必要请不要这样做,肯定有其他方法规避这种危险操作。
28. 避免返回handle指向对象的内部成分
- 即不要返回指向对象数据成员的指针或引用,以保证对象的封装性,防止外部改变对象内部数据。如果非要这样做,请将返回值加上const属性,以禁止修改。
29. 为异常安全所做的努力是值得的
- 这条准则不好总结,大概来说就是对那些可能导致异常发生的函数进行异常捕获并进行适当的处理,以避免内存泄漏。
30. 透彻了解inline的里里外外
- 直接定义在class体内的成员函数默认是内联的,也可以在class体外显式声明内联函数,但最终是否执行内联替换由编译器决定,它只会将那些小型、频繁调用的函数编译为内联函数,这样能尽可能降低代码膨胀并提升程序执行速度。
31. 将文件间的编译依存关系降至最低
- 即让代码依赖声明式而非定义式,这样定义式发生改变不会导致依赖于该定义式的其他代码也需要重新编译。基于此构想的两种方案是:
Handle class
和interface class
。这是在我们平时构建工程的时候经常遇到的两种设计方法。 - 程序库头文件应该以“完全且仅有声明式”的形式存在。其他代码依赖此文件即可。
小结:
以上即总结。明天上班。
《Effective C++》阅读总结(四): 设计、声明与实现的更多相关文章
- Redis源码阅读(四)集群-请求分配
Redis源码阅读(四)集群-请求分配 集群搭建好之后,用户发送的命令请求可以被分配到不同的节点去处理.那Redis对命令请求分配的依据是什么?如果节点数量有变动,命令又是如何重新分配的,重分配的过程 ...
- 【原】AFNetworking源码阅读(四)
[原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...
- 【原】SDWebImage源码阅读(四)
[原]SDWebImage源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 SDWebImage中主要实现了NSURLConnectionDataDelega ...
- GroupBy(..)的四种声明方式的理解及调用
这里我们以 List<Student> studs作为 source,但是注意,studs中的学生可以是分别属于不同的班级和年级 先看GroupBy的第一种声明: public stati ...
- js的数据类型、函数、流程控制及变量的四种声明方式
运算符 基本运算符 加 + 减 - 乘 * 除 / 取余 % 自增 ++ eg: 1++ 或 ++1 自减 -- eg: 1-- 或 --1 注:++或--写在前面表示优先级最高,先进行自增或者自减 ...
- Effective C++笔记04:设计与声明
条款18:让接口easy被正确使用,不易被误用 1,好的接口非常easy被正确使用,不easy被误用.你应该在你的全部接口中努力达成这些性质. 2,"促进正使用"的办法包含接口的一 ...
- EC++学习笔记(四) 设计与声明
条款18:让接口容易被正确使用,不易被误用 必须考虑客户可能做出什么样的错误(防御式编程)std:shared_ptr会自动使用它的"每个指针专属的删除器",消除了"cr ...
- 从SpringBoot启动,阅读源码设计
目录 一.背景说明 二.SpringBoot工程 三.应用上下文 四.资源加载 五.应用环境 六.Bean对象 七.Tomcat服务 八.事件模型 九.配置加载 十.数据库集成 十一.参考源码 服务启 ...
- Effective Java 阅读笔记——方法
38:检查参数的有效性 每当编写方法或者构造器的时候,应该考虑它的参数有哪些限制,在方法的开头处对参数进行检查,并且把这些限制写入文档. 注意: 对于公有方法,应该使用@throws标签在文档中说明违 ...
- 《The Google File System》论文阅读笔记——GFS设计原理
一.设计预期 设计预期往往针对系统的应用场景,是系统在不同选择间做balance的重要依据,对于理解GFS在系统设计时为何做出现有的决策至关重要.所以我们应重点关注: 失效是常态 主要针对大文件 读操 ...
随机推荐
- java中如何创建自定义异常Create Custom Exception
9.创建自定义异常 Create Custom Exception 马克-to-win:我们可以创建自己的异常:checked或unchecked异常都可以, 规则如前面我们所介绍,反正如果是chec ...
- 自己给idea下载Scala插件
场景:有时候在idea上直接下载的scala可能因为太新所以有bug,需要手动下载插件 经验:自己下载完之后发现比较老的版本idea根本不让你装,只能装一些跟idea上推荐的scala相近的版本,感觉 ...
- 以&#开头的是什么编码?
今天遇到了一个网页时繁体的,它的title和meta信息在浏览器中显示正常,但是查看其源码是却是"最新發"这种. 在网上找了半天资料,终于搞明白了. 以在网页中&#开头的是 ...
- struts token令牌机制
利用Struts同步令牌(Token)机制来解决Web应用中的重复提交问题.该方法的基本原理是:服务器端在处理到达的request之前,会将request中的Token值与保存在当前用户session ...
- 面向对象编程-终结篇 es6新增语法
各位,各位,终于把js完成了一个段落了,这次的章节一过我还没确定下面要学的内容可能是vue也可能是前后端交互,但无论是哪个都挺兴奋的,因为面临着终于可以做点看得过去的大点的案例项目了,先憋住激动地情绪 ...
- 简简单单用一下 Hbase
一.Hbase 介绍 https://hbase.apache.org/book.html#_preface https://blogs.apache.org/hbase/ https://resea ...
- python版本共存与语法的注释
python的多种版本共存 首先还是先下载python解释器除最高版本的另外两个版本 个人推荐的是 3.6.8和2.7.14 首先我电脑是win7系统 在计算机属性右键点开高级设置点击环境变量 将下载 ...
- C++五子棋(三)——判断鼠标有效点击
分析 在鼠标左键点击时,我们不能让新棋子在已有棋子的位置落下,同时我们还要让棋子在规定位置落下--棋盘线的交点处. 功能实现 创建数据类型 创建头文件chessData.h和源文件chessData. ...
- uTools .SRT 转 .VTT 格式转换自动化小工具
不想用网上的转换工具,要有网,先上传,再下载,可能还要看广告.有些工具也不是很方便.打算配合uTools的自动化助手插件搞一个一键格式转换.
- Selenium3自动化测试【27】Frame的操作
本篇文章内容摘要 " 讲解Python3+Selenium3如何处理Frame窗体" 同步视频知识与系列知识内容,可关注:[公众号]:柒哥测试:[WX]:Lee-890;[视频号] ...