您的位置:首页 > 编程语言 > C语言/C++

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)参数,就存在建立临时对象而绑定在参数上的可能性。在任何时候只要见到函数返回对象,就会有一个临时对象被建立(以后被释放)。学会寻找这些对象构造,你就能显著地增强透过编译器表面动作而看到其背后开销的能力。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: