尽可能延后变量定义式的出现时间
我们知道定义一个对象的时候有一个不争的事实,那就是分配内存。如果是我们自定义的对象,程序执行过程中会调用类的构造函数和析构函数。
我们打个比方,如果天下雨了,你带把雨伞肯定是值得的。但是,如果你带伞了,今天却没下雨,你是不是感觉自己亏了?的确,亏在了带了却没用,所以伞就变成了累赘。
本节的关键就在于此,如果你定义一个变量或者对象没有被使用,那么就是不完美的代码。
我们看一个代码片段:
std::string encryptPassword(const std::string& psaaword)
{
using namespace std;
string encrypted;
if(password.length()<MinimumPasswordLength)
{
throw logic_error("Password is too short");
}
……//加密密码,把加密结果放到encrypted内
return encrypted;
}
如果,抛出异常,上面的变量encrypted
就没有被使用,虽未被使用,可是却要承受一次构造和一次析构的行为。
改进如下:
std::string encryptPassword(const std::string& psaaword)
{
using namespace std;
if(password.length()<MinimumPasswordLength)
{
throw logic_error("Password is too short");
}
string encrypted;
……//加密密码,把加密结果放到encrypted内
return encrypted;
}
改进的代码跳过了异常,保证定义的encrypted
一定被使用。可是我们知道如果能够调用copy构造函数,就没有必要调用default构造函数+赋值运算符函数。因为前者更高效。
我们继续改进代码:
std::string encryptPassword(const std::string& psaaword)
{
using namespace std;
if(password.length()<MinimumPasswordLength)
{
throw logic_error("Password is too short");
}
string encrypted(password);//定义+赋值
encrypt(encrpted);
……//加密密码,把加密结果放到encrypted内
return encrypted;
}
那么我们在循环中怎么贯彻这种思想呢?
对比一下代码:
Widget w;//定义在循环外
for(int i=0;i < n;++i)
w=……;
……
}
for(int i=0;i<n;++i){
Widget w(……);//定义并赋值
……
}
第一个调用了1个构造函数+1个析构函数+n个赋值操作。第二个调用了n个构造函数+n个析构函数。我们此时需要斟酌一下是赋值操作的效率高还是构造+析构的效率高。事实上,如果双方差距不大,最好选用后者,因为后者对象的作用域更小,可维护性和可理解性更强,更安全。
时间: 2024-11-05 15:56:36