C++编程实用技巧 #32:尽可能地推迟变量的定义
来源:互联网 发布:淘宝开虚拟充值网店 编辑:程序博客网 时间:2024/05/06 11:44
是的,我们同意C语言中变量要放在模块头部定义的规定;但在C++中,还是取消这种做法吧,它没必要,不自然,而且昂贵。
还记得吗?如果定义了一个有构造函数和析构函数的类型的变量,当程序运行到变量定义之处时,必然面临构造的开销;当变量离开它的生命空间时,又要承担析构的开销。这意味着定义无用的变量必然伴随着不必要的开销,所以只要可能,就要避免这种情况发生。
对象encrypted在函数中并非完全没用,但如果有异常抛出时,就是无用的。但是,即使encryptPassword抛出异常(见技巧M15),程序也要承担encrypted构造和析构的开销。所以,最好将encrypted推迟到确实需要它时才定义:
这段代码还不是那么严谨,因为encrypted定义时没有带任何初始化参数。这将导致它的缺省构造函数被调用。大多数情况下,对一个对象首先做的一件事是给它一个什么值,这通常用赋值来实现。技巧12说明了为什么"缺省构造一个对象然后对它赋值"比"用真正想要的值来初始化这个对象"效率要低得多。这一论断在此一样适用。例如,假设encryptPassword中最难处理的部分在这个函数中进行:
于是encryptPassword可以象这样实现(当然,它不是最好的实现方式):
更好的方法是用password来初始化encrypted,从而绕过了对缺省构造函数不必要的调用:
这段代码阐述了本技巧的标题中"尽可能"这三个字的真正含义。你不仅要将变量的定义推迟到必须使用它的时候,还要尽量推迟到可以为它提供一个初始化参数为止。这样做,不仅可以避免对不必要的对象进行构造和析构,还可以避免无意义的对缺省构造函数的调用。而且,在对变量进行初始化的场合下,变量本身的用途不言自明,所以在这里定义变量有益于表明变量的含义。还记得在C语言中的做法吗?每个变量的定义旁最好要有一条短注释,以标明这个变量将来做什么用。而现在,一个合适的名字(见技巧28),再结合有意义的初始化参数,你就可以实现每个程序员的梦想:通过可靠的变量本身来消除对它不必要的注释。
推迟变量定义可以提高程序的效率,增强程序的条理性,还可以减少对变量含义的注释。
还记得吗?如果定义了一个有构造函数和析构函数的类型的变量,当程序运行到变量定义之处时,必然面临构造的开销;当变量离开它的生命空间时,又要承担析构的开销。这意味着定义无用的变量必然伴随着不必要的开销,所以只要可能,就要避免这种情况发生。
正如我所知道的,你的编程方式优雅而不失老练。所以你可能会在想,你决不会定义一个无用的变量,所以本技巧的建议不适用于你严谨紧凑的编程风格。但别急,看看下面这个函数:当口令够长时,它返回口令的加密版本;当口令太短时,函数抛出logic_error类型的异常(logic_error类型在C++标准库中定义,参见技巧49):
// 此函数太早定义了变量"encrypted"string encryptPassword(const string& password){ string encrypted; if (password.length() < MINIMUM_PASSWORD_LENGTH) { throw logic_error("Password is too short"); } 进行必要的操作,将口令的加密版本 放进encrypted之中; return encrypted;}
对象encrypted在函数中并非完全没用,但如果有异常抛出时,就是无用的。但是,即使encryptPassword抛出异常(见技巧M15),程序也要承担encrypted构造和析构的开销。所以,最好将encrypted推迟到确实需要它时才定义:
// 这个函数推迟了encrypted的定义,// 直到真正需要时才定义string encryptPassword(const string& password){ if (password.length() < MINIMUM_PASSWORD_LENGTH) { throw logic_error("Password is too short"); } string encrypted; 进行必要的操作,将口令的加密版本 放进encrypted之中; return encrypted;}
这段代码还不是那么严谨,因为encrypted定义时没有带任何初始化参数。这将导致它的缺省构造函数被调用。大多数情况下,对一个对象首先做的一件事是给它一个什么值,这通常用赋值来实现。技巧12说明了为什么"缺省构造一个对象然后对它赋值"比"用真正想要的值来初始化这个对象"效率要低得多。这一论断在此一样适用。例如,假设encryptPassword中最难处理的部分在这个函数中进行:
void encrypt(string& s); // s在此加密
于是encryptPassword可以象这样实现(当然,它不是最好的实现方式):
// 这个函数推迟了encrypted的定义,// 直到需要时才定义,但还是很低效string encryptPassword(const string& password){ ... // 同上,检查长度 string encrypted; // 缺省构造encrypted encrypted = password; // 给encrypted赋值 encrypt(encrypted); return encrypted;}
更好的方法是用password来初始化encrypted,从而绕过了对缺省构造函数不必要的调用:
// 定义和初始化encrypted的最好方式string encryptPassword(const string& password){ ... // 检查长度 string encrypted(password); // 通过拷贝构造函数定义并初始化 encrypt(encrypted); return encrypted;}
这段代码阐述了本技巧的标题中"尽可能"这三个字的真正含义。你不仅要将变量的定义推迟到必须使用它的时候,还要尽量推迟到可以为它提供一个初始化参数为止。这样做,不仅可以避免对不必要的对象进行构造和析构,还可以避免无意义的对缺省构造函数的调用。而且,在对变量进行初始化的场合下,变量本身的用途不言自明,所以在这里定义变量有益于表明变量的含义。还记得在C语言中的做法吗?每个变量的定义旁最好要有一条短注释,以标明这个变量将来做什么用。而现在,一个合适的名字(见技巧28),再结合有意义的初始化参数,你就可以实现每个程序员的梦想:通过可靠的变量本身来消除对它不必要的注释。
推迟变量定义可以提高程序的效率,增强程序的条理性,还可以减少对变量含义的注释。
- C++编程实用技巧 #32:尽可能地推迟变量的定义
- 尽可能地推迟变量的定义
- (转)条款32: 尽可能地推迟变量的定义
- 变量的推迟定义
- effective C++笔记之条款31、32: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针所指对象的引用、尽可能地推迟变量的定义
- Item 26 推迟变量的定义
- C++编程规范之18:尽可能局部地声明变量
- item26: 尽可能延后变量定义的时间
- 《Effective C++》读书笔记之item26:尽可能延后变量定义式的出现时间
- 《Effective C++》学习笔记条款26 尽可能延后变量定义式的出现时间
- Effective C++:条款26:尽可能延后变量定义式的出现时间
- 《Effect C++》学习------条款26:尽可能延后变量定义式的出现时间
- 【Effection C++】读书笔记 条款26:尽可能延后变量定义式的出现时间
- 读书笔记《Effective C++》条款26:尽可能延后变量定义式的出现时间
- 条款26:尽可能延后变量定义式的出现时间
- 条款26:尽可能延后变量定义式的出现时间
- 条款26:尽可能延后变量定义式的出现时间
- 条款26:尽可能延后变量定义式的出现时间
- 用宏来实现对日期的操作
- 开发者需知的10类工具
- HDU2616 Kill the monster
- 单链表冒泡排序
- hdu_1548 A strange lift
- C++编程实用技巧 #32:尽可能地推迟变量的定义
- LLVM每日谈之十六 LLVM的学习感悟
- Lucene Payload 的研究与应用
- 创建进程间共享内存映射
- C# 时间格式 转 为英文
- C调用Cpp代码时的enum类型定义共享问题
- Interface与Abstract class的异同
- Perl内置特殊变量
- 正能量