Effective C++笔记(五):实现
参考:http://www.cnblogs.com/ronny/p/3754755.html
条款26:尽可能延后变量定义式的出现时间
有些对象,你可能过早的定义它,而在代码执行的过程中发生了导常,造成了开始定义的对象并没有被使用,而付出了构造成本来析构成本。
所以我们应该在定义对象时,尽可能的延后,甚至直到非得使用该变量前一刻为止,应该尝试延后这份定义直到能够给它初值实参为止。
这样做的好处是:不仅可以避免构造(析构)非必要对象,还可以避免无意义的default构造行为。
遇到循环怎么办?此时往往我们会有两个选择:
做法A:1个构造函数+1个析构函数+n个赋值操作 // 在循环外面定变量,在循环内赋值
做法B:n个构造函数+n个析构函数 // 在循环内定义并初始化变量
这时候要估计赋值的成本低还是构造+析构的成本低,另外值得考虑的是对象作用域的问题。除非n特别大,否则优先选择做法B
定义时变量时直接拷贝要好于先用默认构造函数定义,再进行赋值。
条款27:尽量少做转型动作
转型语法通常有三种不同的形式:
1,C风格的转型动作:(T)expression
2,函数风格的转型动作:T(expression)
3,上面的第二种被称为“旧式转型”,C++提供了四种新式转型:
const_cast<T>(expression) //通常用来将对象的常量性转除 dynamic_cast<T>(expression) // 转换为子类,用来决定某对象是否归属继承体系中的某个类型,但是耗费重大运行成本 reinterpret_cast<T>(expression) // 执行低级转型,实际动作取决于编译器,这也就表示它不可移植。如将一个point to int 转型为一个int static_cast<T>(expression) // 强迫隐式转换
请记住:
如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_cast。如果有个设计需要转型动作,试着发展无需转型的设计。
如果转型是必需要,试着将它隐藏于某个函数背后。客户随后可以调用该函数,而不需将转型放进他们自己的代码。
宁可使用C++style(新式)转型,不要使用旧式转型,前者很容易被辨识,而且也比较角着分门别类的职掌。
条款28:避免返回handles指向对象的内部成分
避免返回handles(包括reference、指针、迭代器)指向对象内部。遵守这个条款可以增加封装性,帮助const成员函数的行为像个const,
并将发生“虚吊号码牌”的可能性降至最低。
条款29:为“异常安全”而努力是值得的
异常安全函数即使发生异常也不会泄漏资源或允许任何数据结构败坏。这样的函数区分为三种可能的保证:基本型、强烈型、不抛异常型。
强烈保证往往能够以copy-and-swap实现出来,但“强烈保证”并非对所有函数都可以实现或具备现实意义。
函数提供的“异常安全保证”通常最高只等于其所调用之各个函数的“异常安全保证”中最弱者。
条款30:透彻了解inlining的里里外外
关于inline:
1. inline函数的调用,是对函数本体的调用,是函数的展开,使用不当会造成代码膨胀。
2. 大多数C++程序的inline函数都放在头文件,inlining发生在编译期。
3. inline函数只代表“函数本体”,并没有“函数实质”,是没有函数地址的。
4. inline只是一个申请,编译器可以忽略;
5. 包含循环、递归的函数不要声明为inline,virtual函数只在运行时才知道,inline 函数在执行前就替换,因此virtual函数也不要声明为inline。
值得注意的是:
1. 构造函数与析构函数往往不适合inline。因为这两个函数都包含了很多隐式的调用,而这些调用付出的代价是值得考虑的。可能会有代码膨胀的情况。
2. inline函数无法随着程序库升级而升级。因为大多数都发生在编译期,升级意味着重新编译。
3. 大部分调试器是不能在inline函数设断点的。因为inline函数没有地址。
请记住
1. 大多数inlining限制在小型、被频繁调用的函数身上。这可使日后的调试过程和二进制升级更容易,也可以使潜在的代码膨胀问题最小化,使程序的速度提升机会最大化。
2. 另外,对function templates的inline也要慎重,保证其所有实现的函数都应该inlined后再加inline。
条款31:将文件间的编译依存关系降至最低
支持“编译依存性最小化”的一般构想是:相依于声明式,不要相信于定义式。基于此构想的两个手段是Handles classes和Interface classes。
程序库头文件应该以“完全且仅有声明式”的形式存在,这种做法不论是否涉及templates都适用。
Effective C++笔记(五):实现的更多相关文章
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- [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等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- java effective 读书笔记
java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...
- 《MFC游戏开发》笔记五 定时器和简单动画
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9332377 作者:七十一雾央 新浪微博:http:// ...
随机推荐
- 【Loj#535】花火(线段树,扫描线)
[Loj#535]花火(线段树,扫描线) 题面 Loj 题解 首先如果不考虑交换任意两个数这个操作,答案就是逆序对的个数. 那么暴力就是枚举交换哪个两个数,然后用数据结构之类的东西动态维护逆序对. 但 ...
- 框架----Django之Form组件
Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 一.小试牛刀 1.创建Form类 from d ...
- (转)C#中“EQUALS”与“==”的速度比较
结论: true判断时,用"value" == string是最快的:false判断时,用"value".Equals(string)是最快的. 也就是说:一个 ...
- java发送邮件功能[转]
原文链接:https://blog.csdn.net/jjkang_/article/details/56521959 Javamail遵循两个协议,一个是smtp协议,另一个是pop3协议.一般情况 ...
- c/c++中的预编译指令总结
预处理指令提供按条件跳过源文件中的节.报告错误和警告条件,以及描绘源代码的不同区域的能力.使用术语“预处理指令”只是为了与 C 和 C++ 编程语言保持一致.在 C# 中没有单独的预处理步骤:预处理指 ...
- stout代码分析之一:Duration类
Duration类用于表示时间长度,可精确到纳秒. 代码实现在duration.hpp中,测试代码:duration_tests.cpp 相关api如下: parse, 将字符串转化成Duration ...
- 「Django」rest_framework学习系列-路由
自动生成4个url路由:from rest_framework import routersrouter = routers.DefaultRouter()router.register(r'wrx' ...
- Mysql通过show processlist排查数据库执行慢
RDS for MySQL使用的是InnoDB引擎.不同于MyISAM引擎只提供表锁,InnoDB提供不同级别的锁.但是在我们日常的操作过程中经常由于对数据库不当的SQL操作导致出现长时间的锁,造成其 ...
- Elasticsearch Java API 查询
一.查询的时候,需要建立一个SearchRequestBuilder,这里面将给出对于哪一个index或者type进行查询,并且所有的设置都可以在这里面进行实现,例如模糊查询,范围查询,前缀查询等. ...
- c# windows server安装启动与卸载
使用installutil.exe安装卸载服务时,由于需要指向服务的全路径,由于生成目录往往不是服务发布的最终目录,很不便利,下面介绍两种方式方便操作: 方式一: 项目中加入install.bat与u ...