More Effective C++ ——019_理解临时对象的来源
2015-09-24 17:49
447 查看
条款十九:理解临时对象的来源
什么叫临时变量?先看下面这个例子:template<class T> void swap(T& object1, T& object2) { T temp = object1; object1 = object2; object2 = temp; }
一般人把temp叫做临时变量。但对C++而言,temp根本不是临时变量,它是一个函数的局部对象。
在C++中真正的临时对象是看不见的,它们不出现在源代码中。建立一个没有命名的非堆(
non-heap)对象会产生临时对象,因为局部对象生命周期短数据易被销毁,没有临时对象(副本)产生则数据传递不了
临时对象产生时机:
1) 函数参数调用时(为了使函数成功调用而进行隐式类型转换)
2)函数返回对象时
临时对象产生开销
产生临时对象带来构造和析构函数调用的开销,对程序的影响不可忽悠,有两个方法可以消除。
注:一种是重新设计你的代码,不让发生这种类型转换。(见条款5)。另一种方法是通过修改软件而不再需要类型转换(见条款21)。
C++中仅当通过传值(by value)方式传递对象或传递常量引用(reference-to-const)参数时,才会发生这些类型转换。当传递一个非常量引用(reference-to-non-const)参数对象,就不会发生。
函数参数调用时
a)by value——add(T a,T b),add(T* a,T* b)T不能是数组类型,数组作为函数参数会退化为指针类型就是很好证明(复制指针只需要4个字节内存),但拷贝数组消耗大量内存及降低效率。
b)reference-to-const——add(const T& a)
const 要求不能改变被引用对象的值。所以必须要有临时对象产生,否则,会修改到实参的数值。
c)reference-to-non-const——add( T& a)
没有const 修饰时,引用要求能修改被引用的实参的数值。如果有临时对象产生,则达不到修改实参的效果。
函数返回对象
因为局部对象生命周期有限,无法传递内容出去,需要建立副本。如果你不想付出这样的开销。对于这种函数,
const Number operator+(const Number& lhs,const Number& rhs);
你可以切换到operator=,而避免开销(见条款22)。
但对于大多数返回对象的函数来说,无法切换到不同的函数,从而没有办法避免构造和释放返回值。至少在概念上没有办法避免它。
可喜的是概念和现实之间又有一个黑暗地带,叫做优化,有时你能以某种方法编写返回对象的函数,以允许编译器优化临时对象。这些优化中,最常见和最有效的是返回值优化(见条款20)
总结:临时对象是有开销的,所以你应该尽可能地去除它们,然而更重要的是训练自己寻找可能建立临时对象的地方。在任何时候只要见到常量引用(reference-to-const)参数,就存在建立临时对象而绑定在参数上的可能性。在任何时候只要见到函数返回对象,就会有一个临时对象被建立(以后被释放)。学会寻找这些对象构造,你就能显著地增强透过编译器表面动作而看到其背后开销的能力。
相关文章推荐
- C语言strtok()函数:字符串分割
- VC++_截取字符串
- effective c++ 条款23 perfer nonmember nonfreind function to member function
- C++的引用类型
- 细谈select函数(C语言)
- C++中template的.h文件和.cpp文件的问题
- 关于全局变量笔记
- c++中rand()函数返回值范围
- C++中输入输出的十六进制八进制
- c++中的构造函数
- 详解C++编程中的文件流与字符串流
- 数据机构与算法分析:C语言描述 第五章——Priority Queues(Heaps)中的5.4.2 Event Simiulation
- C++二分法在数组中查找关键字的方法
- C++中的重载
- 黑马程序员---C语言学习笔记之数组的基本概念和分类
- 解读C++编程的相关文件操作
- C++开源矩阵计算工具——Eigen的简单用法
- C语言strcpy,strncpy的用法
- C++中的string常用函数用法总结
- C++ atof函数