EC之Implementations
来源:互联网 发布:网络维护工具套装 编辑:程序博客网 时间:2024/06/05 02:11
条款26:Postpone variable definitions as long as possible
只要你定义了一个类变量,你就得承受相应的构造和析构成本——即使该变量最终未被使用。或许你觉得你不会定义一个不使用的变量,那不妨考虑下面这个函数,它返回加密后的密码,但如果密码太短,函数会抛出一个类型为logic_error的异常:
//这个函数过早定义变量"encrypted"std::string encryptPassword(const std::string& password) { using namespace std; string encrypted; if (password.length() < MinimumPasswordLength) { throw logic_error("Password is too short"); } ... //必要处理 return encrypted;}
如果有异常抛出,对象encrypted就未被使用,其构造和析构成本就不是必要的。所以,最好延后encrypted的定义,直到确实需要它:
//这个函数延后"encrypted"的定义,直到确实需要它:std::string encryptedPassword(const std::string& password) { using namespace std; if (password.length() < MinimumPasswordLength) { throw logic_error("Password is too short"); } string encrypted; .. //必要处理 return encrypted;}
但是这段代码也并非秾纤合度,因为encrypted虽获得了定义却没有任何实参作为初值。这意味着调用的是其default构造函数。许多时候你该对对象做的第一次事就是给它一个初值。条款4曾解释通过default构造函数构造出一个对象然后对它赋值比直接在构造时指定初值效率差,因此你不只应该延后变量的定义直到使用该变量为止,甚至应该延后定义知道能够给其初值位置。这样不仅能够避免构造和析构非必要对象,还可以避免无意义的default构造行为。
假设上述函数在对变量"encrypted”处理之前以"password“为初值,那么定义"encrypted"的最佳做法应该如下:
std::string encryptedPassword(const std::string& password) { ... //检查长度 std::string encrypted(password); ... //必要处理 return encrypted;}
如果碰到循环怎么办呢?如果变量只在循环内使用,那么该把它定义于循环外并在每次迭代时赋值给它,还是把它定义于循环内?下面两个结构,哪个比较好?
//方法A:变量定义于循环外Widget w;for (int i = 0; i < n; ++i) { w = 取决于i的某个值; ...}//方法B:变量定义于循环内for (int i = 0; i < n; ++i) { Widget w(取决于i的某个值); ...}
考虑两种方法的成本:
方法A:1个构造函数+1个析构函数+n个赋值操作
方法B:n个构造函数+n个析构函数
如果赋值成本低于构造+析构成本,做法A比较高效,特别是n很大时。但A中w的作用域比B中更大,这有时会降低程序的可读性和可维护性。因此除非你知道赋值成本比构造+析构成本低,并且正在处理的代码对效率的要求很高,否则你应该使用方法B。
条款27:Minimize casting
首先让我们回顾一下转型的语法。为将expression转型为T
C风格的转型如下:
(T)expression
函数风格的转型如下:
T(expression)
以上两种形式并无差别,纯粹只是小括号的位置不同。我们称这两种形式为旧式转型。
C++还提供四种新式转型:
const_cast<T>( expression )dynamic_cast<T>( expression )reinterpret_cast<T>( expression )static_cast<T>( expression )
它们的作用各不相同:
- const_cast用来移除对象的常量性。它是唯一一个有此能力的C++-style转型方式。
- dynamic_cast用来执行安全向下转型。它是唯一无法由旧式转型执行的动作,也是唯一可能耗费重大运行成本的转型动作
- reinterpret_cast用来执行低级转型,结果往往取决于编译器,这意味着它不可移植。
- static_cast用来进行显式类型转换。
条款28:Avoid returning "handling" to object internals
条款29:Strive for exception-safe code
条款30:Understand the ins and outs of inlining
条款31:Minimize compilation dependencies between files
- EC之Implementations
- EC之Resource Management
- Effective C++ 读书笔记之Part5.Implementations
- EC (-)
- EC
- EC之Designs and Declarations
- EC-Final之金工实习
- EC-Final之质因子
- PayPal EC 快速结账之集成攻略
- EC之Accustoming Yourself to C++
- EC之Constructors,Destructors, and Assignment Operators
- EC修炼之道—代码架构
- EC修炼之道—ECSCI
- EC修炼之道—Thermal
- EC修炼之道—SMBUS
- ec-final 上海打铁之旅
- ECSide标签属性说明之<ec:column>
- GlusterFS企业级功能之EC纠删码
- js学习
- Oracle中的几个概念——db_name db_domain instance SID
- Android异步下载网络图片(其一)
- Java调用XML的方法之DocumentBuilderFactory
- ios的@property属性和@synthesize属性
- EC之Implementations
- Android异步下载网络图片(其二)
- 下拉刷新ListView的实现原理
- 实现DropDownList 无刷新的联动效果
- 移植SlidingMenu Android library和安装example出现的问题解决
- BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)
- InputStream读取数据
- c语言简单的链表
- ContentProvider 对SQLite数据共享