C++ 临时对象

1、什么是临时对象?

  swap方法中,常常定义一个temp对象,这个temp对象不是临时对象,而是局部对象。这里所说的临时对象是不可见的,在原代码中是看不到的。

2、为什么会产生临时对象?

  a、客户期望的数据与你提供的数据不一致,需要隐式类型转换,中间需要适配一下,建立一个临时对象。

  b、方法返回值,他是没有名字的,起到一个传递作用,方法内部的局部对象-->方法返回值-->主调方法中的接受对象。

  c、异常处理,分为两个过程:抛出异常,捕获异常。抛出异常相当于return 方法内的局部对象,外部要有一个匿名的临时对象接收。catch语句类似于调用方法,将临时对象传给catch语句。

3、对于第一种情况,只有传值和传const引用,才有可能导致临时对象。传一般的引用不会,考虑:

  double d = 3.14;

  int &ri = d;

  double 与int 类型不一致,需要适配,会创建一个临时对象int temp,temp的值为5,然后把temp传递给ri,如果修改ri的内容,只会导致temp的内容发生变化,而不会改变d的内容,这与程序员的期望不一致,造成错觉。因此,编译器拒绝这种隐式类型转换。

  但是,如果是const引用,为什么可以呢?

  因为const承诺了不会修改内容,就不会出现上面的情况,给程序员造成错觉。

4、只要有临时对象,就会出现构造方法和析构方法。因此要尽量避免临时对象。

5、对于第一种情况,解决办法是:尽量不要发生转型。

6、对于第二种情况,解决办法:

  a、避免返回对象,对于有些有返回值的方法,可以在主调方法中创建一个局部对象,把局部对象,传递引用给被调方法,在被调方法中修改局部对象的引用,不再需要返回值。

  b、对于必须返回对象的情况,让方法返回引用或者指针都是不合适的(引用:方法返回时,对象销毁了,引用指向的是垃圾;指针:客户,也就是主调方法需要负责内存的释放)。也就是说,无法消除返回对象。这种情况下,可以采用Constructor Arguments代替被调方法中的局部对象,不仅能够消除方法内的局部对像,还可以消除方法返回时的临时对象,这就是返回值优化(RVO = Return Value Optimization)。

7、对于第三种情况,抛出异常类似于方法返回值的过程,抛出异常相当于return方法内的局部对象,外部需要一个匿名的临时对象接收,这个临时对象不能消除。同时捕获异常的catch(exception ex)类似于调用方法,为了避免再次copy构造对象,catch语句使用 reference

posted on 2013-11-13 17:38  Andy Niu  阅读(2682)  评论(0编辑  收藏  举报