《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在系统设计时为何做出现有的决策至关重要.所以我们应重点关注: 失效是常态 主要针对大文件 读操 ...
随机推荐
- Codepen 每日精选(2018-4-20)
按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以打开原始页面. 图书打开的交互效果https://codepen.io/jcoulterde... 进度条交互效果http ...
- for 循环详解
学习目标: 掌握 for 循环的使用 学习内容: 1.for语法 for(初始化语句; boolean表达式; 循环后操作语句) { 循环体; } 流程图如下: 特点: 初始化语句:只在循环开始时执行 ...
- 解决vue安装时出现vue --version或vue不是内部命令的问题
1. 试图全局配置 vue 的环境变量,找到 vue.cmd 的路径,然后进行配置. 问题:在文件搜索中,没有找到 vue.cmd,失败. 1.npm i npm -g 全局 update 了 npm ...
- 使用pyttsx3实现简单tts服务
操作系统:Windows 10_x64 python版本:Python 3.9.2_x64 pyttsx3版本: 2.90 pyttsx3是一个tts引擎包装器,可对接SAPI5.NSSS(NSS ...
- Leetcode541/151之String与char数组与StringBuffer
String与char数组与StringBuffer 通常情况下遇到删除字符或者反转字符串时需要将String转为char数组或者StringBuffer String与char数组 char [] ...
- SLF4J 报错解决:No SLF4J providers were found
1.解决SLF4J报错 我们在自己的项目中使用了SLF4J,或者引入了某开源项目时,他的项目中用了SLF4J,运行时会报如下的错误: SLF4J: Failed to load class " ...
- 帝国CMS内容页模板过滤清理简介smalltext前后空格的方法!
在内容模板你需要调用的地方使用如下代码输出简介即可过滤简介smalltext前后的空格了: <? $qian=array(" "," ","\t ...
- Unity制作特写镜头
##类似这种效果 黑边的大小可以自行调整 ###这里为了方便直接用两个Button绑定了方法,有需要自行调用方法 ##1.首先制作上下两层黑边 创建Canvas然后在canvas上新建空物体,命名为C ...
- Machine Learning 学习笔记 01 Typora、配置OSS、导论
Typora 安装与使用. Typora插件. OSS图床配置. 机器学习导论. 机器学习的基本思路. 机器学习实操的7个步骤
- 那些年uniapp踩过的坑之-------搜索框插件uni-search-bar字体和图标居中的问题
用uniapp必不可少的就是搜索框 但是公司要求的是这样滴 但是 uni-search-bar这个插件给我的偏偏是这样子滴 这个时候我以为是简简单单的样式问题,但是多方调试无果之后才发现,这两个根本不 ...