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

本文探讨了在编程中推迟变量定义的策略,旨在提高程序的清晰度和效率。通过延迟变量定义直到真正需要使用它,可以避免不必要的构造和析构过程,减少资源消耗。同时,文章还讨论了循环体内定义变量与循环体外定义变量的权衡,提供了选择最佳实践的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

尽可能延后变量定义的出现,这样可以增加程序的清晰度并改善程序效率 
当定义一个变量(尽管从未使用),当程序控制流到达这个变量定义时,仍然会耗费构造和析构成本。
考虑下述代码:
//过早定义变量s1
       std::string fun1(const std::string& s1)
       {
              using namespace std;
              string s2;
              if(s1.length()<minlength)
              {
                     throw error("s1 is too short");  //s1太短 则抛出异常
              }
              ...       //必要操作
                     return s2;
       }

       上述代码在抛出异常,并没有使用s2时,你仍需花费s2的构造和析构成本,改进如下:
//延后s2定义 直到真正需要它
       std::string fun1(const std::string& s1)
       {
              using namespace std;
              if(s1.length()<minlength)
              {
                     throw error("s1 is too short");  //s1太短 则抛出异常
              }
              string s2;
              ...   //必要操作
              return s2;
       }
改进后的代码仍然不够完善,因为s2并无任何实参作为初值。条款4说明“通过default函数构造一个对象然后对它赋值”比“构造对象是直接指定初值”效率差。该分析同样适用于此代码。

考虑以下代码:
假设s2的主要操作在以下函数中进行
void fun2(std::string&  s);  //在适当的地方处理s

于是fun1实现如下,虽然还不完善
std::string fun1(const std::string& s1)
       {
       ...          //同前 检查length
       std::string s2;  //默认构造s2
       s2=s1;           //赋值给s2;
       fun2(s2);
       return s2;
       }

       根据“直接在构造时指定初值”改进代码如下:
//定义并初始化s2的最佳做法
       std::string fun1(const std::string& s1)
       {
              ...  //同前
              string s2(s1);    //通过复制构造函数
              fun2(s2);
              return s2;
       }

这样我们想到“尽量延后变量定义”的真正含义,不应只延后变量定义直到使用该变量的前一刻为止,更应是延后变量定义直到能给它初始值实参为止。
这样可以避免无意义的构造和析构行为,也能避免无意义的默认构造行为
 
当遇到循环时,应定义变量于循环内还是循环外?考虑下述代码:
//方法A  定义于循环外
       Widget w;
       for(int i=0;i<n;++i)
       {
              w=取决于i的某个值;
              ...
       }


   //方法B 定义于循环内
       for(int i=0;i<n;++i)
       {
              Widget w(取决于i的某个值);
              ...
       }

方法A:1构造+1析构+n赋值
方法B:n构造+n析构

	很显然,如果成本  1赋值<(1构造+1析构),应先A方案,特别是当n很大时。否则选B方案。

	此外,A定义的w的作用域(覆盖整个循环)比B大,有时会对程序的可理解性和易维护性造成冲突。

	所以除非1、知道赋值成本比构造加析构成本低,2、正在处理代码中效率高度敏感部分,时选用A,否则应该选用B方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值