尽量延后变量定义式的出现时间《Effective C++》

来源:互联网 发布:手机淘宝没有卖家中心 编辑:程序博客网 时间:2024/05/21 11:25

读《Effective C++》知识点整理

背景:

只要定义了一个变量而其类型带有一个构造函数或析构函数,那么程序的控制流到达这个变量定义式时,你便得承受构造成本。

当这个变量离开作用域时,你便得承受析构成本。即使这个变量最终并未被使用,仍需考虑这些成本。因此你必须尽可能避免这情况

示例1:

std::string encryptpassword(const std::string& password)
{
using namespace std;
string encrypted;
if(password.length() < 10)
{
throw logic_error("Password is too short");
}

... 
return encrypted;
}

encrypted这个变量未完全使用。但必须承担一次构造成本和析构成本。

优化1:

std::string encryptpassword(const std::string& password)
{
using namespace std;

if(password.length() < 10)
{
throw logic_error("Password is too short");
}

string encrypted;

....
return encrypted;

}

encrypted这个变量完全使用。但程序抛出异常却不必承担一次构造成本和析构成本。


存在的问题:

encrypted虽然定义却无任何实参作初值。

意味:encrypted调用的是default构造函数

建议:直接在构造时指定初始值,比通过默认构造函数构造出一个对象之后,再对它赋值的效率高。

承上,优化2:

std::string encryptpassword(const std::string& password)
{
using namespace std;

if(password.length() < 10)
{
throw logic_error("Password is too short");
}

std::string encrypt(password);

string encrypted(encrypt);

....
return encrypted;

}


结论1:尽量延后,不只是延后变量的定义,直到非用不可为止,还应该延后这份定义直到能给它初值实参为止。

优点:不仅能避免构造和析构非必要对象,还可以避免无意义的默认构造行为。

更深一层,使用明显具有意义的初值将变量初始化,还可以附带说明变量的目的。


示例2:

//方法A:string对象定义循环外

string S;

for (int i = 0; i< n; ++i)

{

S = 根据 i 得到的某个值;

}

//方法B:string对象定义循环内

for (int i = 0; i< n; ++i)

{

string S(根据 i 得到的某个值);

}

针对string对象的使用成本:

方法A:1个构造函数+1个析构函数+n个赋值操作;

方法B:n个构造函数+n个析构函数


谁的成本大?

答:如果class的一个赋值成本低于一组构造+析构成本,方法A整体而言比较高效;尤其当n很大的时候,效果明显。反之,方法B更好。

方法A的使用,要求:

1)明确赋值成本低于构造+析构成本;

2)明确当前处理的逻辑/业务对效率高度敏感。

否则,使用方法B。

阅读全文
0 0
原创粉丝点击