C++标准允许编译器对临时对象的产生有完全的自由度。
T a, b;
c = a + b;
T operator+ (const T& a, const T&b);
如果没有经过优化,则会产生临时对象。
T tem; //不调用构造函数
tem.operator+(a , b);
c.operator=(tem);
tem.T::~T(); //临时对象被摧毁
而如下的操作:
T c = a+b;
经过NRV优化,则不会有t临时对象产生。
c++伪代码:
T c; //不调用构造函数
c.operator+(a+b);
而
a+b;
这时候有必要产生一个临时对象,以放置预算后的结果,才可以用于表达式中。如
T v;
v = a + b + c;
C++规定临时对象的生命周期,在完整的表达式之后才结束。
string a("a"), b("b"), c("c"), d("d");
例如printf("%s",a + b);
其中string定义了一个转换运算符
string::operator const char* () { return _str; }
这里产生的临时对象会在printf()完之后释放,不然会导致错误。在c++标准中,临时对象的被摧毁,应该是对完整表达式求值过程中的最后一个步骤,该完整表达式造成临时对象的产生。
什么是完整表达式,简单地说,它是被涵括的表达式中最外围的那个。下面这个式子:
((objA > 1024) && (objB >2)) ? objA + objB : foo(objA, objB);
任何一个子表达式所产生的任何一个临时对象,都应该在完整表达式被求值完成后才可以毁去。
但有两个例外,一个是表达式被用来初始化一个object时。
bool b;
....
string c = b ? str1 + str2 : str3 + str4;
这里产生的临时对象应该在c初始化完成之后被摧毁。
第二个例外是,临时对象被引用时。
const string& str = "abc";
产生出这样的程序代码
string temp;
temp.string::string("abc");
const string& str = tem;
此时临时对象tem与str 的生命周期相同。