1.是否会产生一个临时对象,视编译器的进取性和代码操作发生时的语境而定。C++标准中指出编译器对临时性对象有完全的*度。
2.在新开辟的内存上以拷贝的方式构造对象时,几乎所有编译器都不会产生一个临时性对象。
T c=a+b; //其中加法运算符形式如下: T operator+(const T&,const T&); //或 T T::operator+(const T &);
上面的表达式可能会通过拷贝构造函数直接将a+b的值放到c中,同时可能会有NRV发生,不会调用构造函数和析构函数。然而下面这种情况几乎确定会产生临时对象。
c=a+b; //会被转换为如下伪码① T temp; temp.operator+(a,b); c.operator=(temp); temp.T::~T(); //而不会转换为这样② c.T::~T(); c.T::T(a+b);
这种情况下,不像之前那种情况,不能直接传递c到运算符函数中,因为c的内存不是一块新鲜的地址,需要先将其进行清理。而不选则②的原因是,拷贝构造函数、析构函数和拷贝赋值运算符都是可以由使用者提供的,这可能导致①和②的语义不同,所以编译器会选择与最初表达式语义最符合的情况①。
3.临时对象的生存周期
①临时对象被摧毁应该是对创造该临时对象的完整表达式求值过程中的最后一个步骤。但是会有②和③两个特例
②凡是持有表达式执行结果的临时对象,应该留存到对象的初始化操作完成为止。
③如果一个临时对象被绑定与一个引用或指针,知道被初始化的引用的生命结束,或直到临时对象的生命范畴结束,视哪一种情况先到达而定。
4.C++标准没有规定临时对象储存的位置,但是根据上面临时对象的周期来看,大多数是储存在代码区即栈。
5.临时对象的产生可能导致大量的内存存取过程,编译器可以通过反聚合(把复杂的式子标称很多简单的式子相加)来提高效率。