临时对象的生成
如果我们有函数如下:1
T operator+(const T&,const T&);
那么在执行该函数时,可能会生成一个临时对象以存储需要传回的对象。是否会产生临时对象由很多因素决定,其中我们需要的知识点是NRV。
由于市场竞争的关系,大多数编译器均采取了一系列优化策略,以至于如下表达式:1
T c = a+b;
几乎不可能产生临时对象。但值得注意的是下一种情况——与表达式意义相当的assignment statement:1
c = a+b;
它会直接导致临时对象的生成:1
2
3
4T temp;
temp.operator+(a,b);
c.operator=(temp);
temp.T::~T();
我们可以认为,初始化操作总比赋值操作效率更高。
此外,还有一种生成临时对象的情况:没有出现目标对象:1
a+b;
这会产生一个临时对象,用以放置运算后的结果。
临时对象的生命期
在C++ standard之前,临时对象的生命期并没有明确指定,完全由各编译器生产厂商决定。而C++ standard定义如下:临时对象的被摧毁,应该是对full expression求值过程中的最后一个步骤,该表达式造成临时对象的产生。
什么是full expression?你可以认为是被涵括的表达式中最外围的那个:1
((objA>1024) && (objB>1024))?objA+objB:foo(objA,objB);
比如该三目运算符表达式即为full expression,任何一个子算式产生的任何一个临时对象,都应当在完整表达式被求值完成后销毁。
此外,C++ standard又有两个特例:
- 凡含有表达式执行结果的临时对象,应该存留到object的初始化操作完成为止。
这种做法提高了初始化效率,防止了另一个临时对象的生成。 - 如果一个临时性对象被绑定于一个reference,对象将会被残留,直到被初始化的reference声明结束,或临时对象的生命期结束。