您的位置:首页 > 其它

条款26:尽可能延后变量定义式的出现时间

2009-06-25 09:49 323 查看
条款26:尽可能延后变量定义式的出现时间
(Postpone variable definitions as long as possible.)

内容:
由于定义一个类变量时,你就必须承担起构造和析构的负担.所以我们要尽量减少定义一些我们不用的对象,
估计你现在对这条约束很不在意,我不用它为啥要定义它,我定义对象变量后肯定我会用它的嘛,呵呵,话不要说
的太早有些时候,你的"不留心"会"出卖"你做出的这个承诺.
比如下面这个例子,你需要加密密码,如果密码太短,抛出异常,否则返回加密后的版本:
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
变量没有使用就开始析构了,浪费了我们辛辛苦苦构造出来它,如何改正呢?这个问题不大,我们延后它的定义式不就行
了么,代码修改如下:
std::string encryptPassword(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构造行为.
如果在循环语句中定义变量,我们将需要考虑到它的构造(析构)成本与赋值成本所承受成本的大小比较问题,看下面这
两种形式:
//A :变量定义于循环外
Widget w;
for(int i = 0; i < n; i++){
w = ..;
...
}
//B:变量定义于循环内
for(int i = 0; i < n; i++){
Widget w(xxx);
...
}
两种形式的成本如下:
A: 1个构造函数 + 1个析构函数 + n个赋值函数
B: n个构造函数 + n个析构函数
我们开始比较:如果Widget的构造析构成本比赋值成本要高的话,无疑A的做法总体效率要高;反之则B的做法效率高.

请记住:
◆ 尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: