Effective C++ 条款26

尽可能延后变量定义式的出现时间

我们知道定义一个对象的时候有一个不争的事实,那就是分配内存。如果是我们自定义的对象,程序执行过程中会调用类的构造函数和析构函数。

我们打个比方,如果天下雨了,你带把雨伞肯定是值得的。但是,如果你带伞了,今天却没下雨,你是不是感觉自己亏了?的确,亏在了带了却没用,所以伞就变成了累赘。

本节的关键就在于此,如果你定义一个变量或者对象没有被使用,那么就是不完美的代码。

我们看一个代码片段:

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-08-27 13:28:04

Effective C++ 条款26的相关文章

《Effective C++》之条款26:尽可能延后变量定义式的出现时间

<Effective C++> 条款26:尽可能延后变量定义式的出现时间 只要你定义了一个变量而其类型带有一个构造函数和析构函数,那么当程序的控制流到达这个变量定义式时,你便得承受构造成本:当这个变量离开作用域时,你便得承受析构成本.即使这个变量最终并未被使用,仍需耗费这些成本,所以你应该尽量避免这种情形. 对于"尽可能延后"的理解: 不只应该延后变量多的定义,直到非得使用该变量的前一刻为止,甚至应该尝试延后这份定义直到能够给它初始实参为止.如果这样,不仅能够避免构造(析构

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

(一) 那么当程序的控制流到达这个变量定义时,变承受构造成本:当变量离开作用域时,便承受析构成本. string encryptPassword(const std::string& password) { using namespace std; string encrypted; if(password.length() < MinimumPasswordLengt) { throw logic_error("Password is too short") } -//

《Effective C++》学习笔记——条款26

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 杂谈: <Effective C++>已经看到第26个条款了,总共55条,看了也大约近一半了. 刚开始看这本书,还是因为当时想提高一下C++,然后搜了搜书想看一下, 当时不知道在哪看到了一句话: 学C++的人,分为两种读过这本书的和没读过这本书的.(话说当时还

Effective C++ Item 26 尽可能延后变量定义式的出现时间

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率. 示例: //这个函数过早定义变量"encrypted" std::string encryptPassword(const std::string &password){ using namespace std; string encrypted; if(password.length() <

More Effective C++ 条款35 让自己习惯于标准C++ 语言

(由于本书出版于1996年,因此当时的新特性现在来说可能已经习以为常,但现在重新了解反而会起到了解C++变迁的作用) 1. 1990年后C++的重要改变 1). 增加了新的语言特性:RTTI,namespaces,bool,关键词mutable和explicit,enums作为重载函数之自变量所引发的类型晋升转换,以及"在class 定义区内直接为整数型(intergral) const static class members设定初值"的能力. 2). 扩充了Templates的特性

More Effective C++ 条款32 在未来时态下发展程序

1. 所谓"在未来时态下发展程序",指的是是程序需要具有良好的可扩展性和可维护性,它要求程序:功能齐全,接口易用,代码泛化,以下原则有助于实现这一目标: 1). 以C++本身表现各种规范而不是仅仅依赖于注释:如果某个class不打算作为基类,那么就应该以C++语法阻止派生(条款26);如果一个class要求所有对象实体在heap内产生,就以C++语法严格厉行这项约束(条款27),如果copying和assignment对某个class没有意义,就声明为private... 2). 如果

effective c++ 条款4 make sure that objects are initialized before they are used

1 c++ 类的数据成员的初始化发生在构造函数前 class InitialData { public: int data1; int data2; InitialData(int a, int b) { data1 = a: //this is assignment data2 = b; //this is assignment } /* InitialData(int a, int b):data1(a),data2(b) //this is initial {} */ } 2 不同cpp文

More Effective C++ 条款34 如何在一个程序中结合C++和C

1. C++和C混合使用的前提之一就是编译器产生兼容的目标文件(.lib和.dll等).所谓"兼容",指的是编译器在"预编译器相依的特性上"一致,如int和double大小,参数压栈机制等,只有在这个基础上才能讨论结合使用C++和C模块的问题. 2. 在1的基础上,要结合使用C++和C的模块,主要有以下几点需要注意: 1). name mangling(名称重整) Name mangling是C++用于支持函数重载的机制,它对重载的函数名称进行一定改变,使得每个函数

Effective C++ 条款3 尽可能用const

1. const可被施加于任何作用域内的对象,函数参数,函数返回类型,成员函数本体.用const修饰指针,如果const出现在*之前,表明指针不能更改所指向的对象的内容,如果const出现在*之后,表明指针只能指向同一块内存.另外int const*p和const int*p含义相同.如果对象成员有普通指针,那么构造该类的一个const对象时,const修饰使得该指针只能指向同一块内存,但指针指向的内容可以改变. 2. 将某些东西声明为const可以帮助编译器侦测出错误用法. 3. 编译器强制实