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

一、变量定义的成本

  • 只要你定义一个变量,该变量带有构造函数与析构函数,那么:
    • 当你定义这个变量时就要执行它的构造函数
    • 变量生命周期结束后就要执行他的析构函数

二、尽量延迟变量定义的时间

  • 变量定义需要执行构造与析构函数,因此在某些情况下为了提高程序的效率,应该延迟变量定义的时间。请看下面的演示案例:

演示案例

  • 下面定义一个函数,用来对密码进行加密,如果参数传入的密码过段就抛出一个logic_error异常(见条款54)
//参数:要加密的密码

//返回值:加密后的密码

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,但是如果函数执行到if的时候程序抛出了异常,那么你就需要承担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使用的是默认的构造函数,在条款4中我们说过“通过默认的构造函数构造对象”比“直接在构造时指定初值”的效率差。因此我们应该避免变量定义时使用默认的构造函数

演示案例

  • 下面我们定义的变量encrypted使用默认构造函数,然后再以拷贝辅助运算符将参数赋值给它
//参数:要加密的密码

//返回值:加密后的密码

std::string encryptPassword(const std::string& password)

{

    using namespace std;

    if (password.length()<MinimumPasswordLength) {

        throw logic_error("Password is too short");

    }

    string encrypted; //使用默认的构造函数

    encrypted=password; //然后再使用拷贝赋值运算符进行赋值

    //...


    return encrypted;

}
  • 上面的效率比较低, 因此我们建议在变量定义时直接构造
//参数:要加密的密码

//返回值:加密后的密码

std::string encryptPassword(const std::string& password)

{

    using namespace std;

    if (password.length()<MinimumPasswordLength) {

        throw logic_error("Password is too short");

    }

    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的某个值;

}
  • 对于Widget来说,上面付出的代价有:
    • 做法A:1个构造函数+1个析构函数+n个赋值操作
    • 做法B:n个构造函数+n个析构函数
  • 如果类的赋值成本低于一组构造+析构,那么做法A可选,尤其当n值很大的时候;否则做法B比较好
  • 做法A中w的作用域更大,如果与程序的可理解性或易维护性造成冲突的话,选择B比较好

五、总结

  • 尽可能延后变量定义式的出现。这样做可增加程序的清晰度并改善程序效率
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值