有关临时对象的生命周期有三种情况:
- 一般情况:临时性对象的被摧毁,应该是对完整表达式(full-expression)求值过程中的最后一个步骤。该完整表达式造成临时对象的产生。
以及两个特殊情况
- 凡含有表达式执行结果的临时性对象,应该存留到object的初始化操作完成为止。
- 如果一个临时性对象被绑定于一个reference,对象将残留,直到被初始化之reference的生命结束,或直到临时对象的生命范畴(scope)结束
所以引用会提升临时变量的生命期,而使用const可以防止修改指向临时对象的引用,而且不加const也会报错:非常量引用只能绑定到左值。
但是,const引用提升生命期,是将临时变量的“在full expression结束销毁”提升为“在const引用生命结束销毁”
例如下面这个例子:
#include <iostream>
#include <string>
using namespace std;
const string& Func()
{
return "123";
}
int main()
{
string s = Func();
cout << s << endl;
return 0;
}
“123”是在Func函数的内部,也就是该函数的栈上,出了函数就没有了。
临时变量的生命周期本来只是创建该临时变量的表达式,表达式结束后,被析构,const引用将其生命周期提升到该函数结束时(如果是全局const引用变量,那自然就是提升到整个程序的生命周期),函数结束被析构,而并不会将其生命周期提升到函数外部,函数结束时,也会被析构掉的。
const引用其实和右值引用差不多,都是都是将临时变量的生命周期从该表达式提升到函数。
所以正确的写法应该是:
#include <iostream>
#include <string>
using namespace std;
string Func()
{
return "123";
}
int main()
{
const string& s = Func();
cout << s << endl;
return 0;
}
参考:
c++ 临时变量问题的讨论1
c++ 临时变量问题的讨论2
Temporary Objects - Programming languages — C++
Lifetime of a temporary - cppreference