作为 const 引用返回的 class 的生命周期
Lifetime of a class returned as const reference
如果我尝试 return 来自函数的字符串文字,我可以制作这两个版本:
std::string get_val()
{
return "1234";
}
const std::string & get_ref()
{
return "1234";
}
然而,让我感到困惑的是,我认为你需要一个长期存在的对象,以便拥有一个左值引用(我正在阅读 const std::string &
作为左值引用,也许我错了) .
为什么这行得通? "1234"
在我从函数 return 之后住在哪里?
第二个实现无效。
实际上 return "1234"
创建了一个驻留在堆栈上的临时(右值)字符串对象(就好像它是 return std::string("1234")
一样),一旦它 returns 返回的引用就变成了悬空引用,因为它在堆栈内存中。
最近的编译器会发出如下警告:
<source>: In function 'const string& get_ref()':
<source>:5:12: warning: returning reference to temporary [-Wreturn-local-addr]
5 | return "1234";
| ^~~~~~
std::string get_val()
{
return "1234";
}
在这种情况下,创建了一个字符串类型的对象,然后调用移动构造函数(通常会说复制,但由于编译器优化,更可能调用移动)以将值存储在目标变量中
const std::string & get_ref()
{
return "1234";
}
在这里你是return对临时本地对象的引用,所以当字符串的构造函数完成用“1234”构造字符串对象并且return被称为对象时之后被销毁,因为创建的对象在本地范围内是临时的。它应该向您抛出一个错误
如果我尝试 return 来自函数的字符串文字,我可以制作这两个版本:
std::string get_val()
{
return "1234";
}
const std::string & get_ref()
{
return "1234";
}
然而,让我感到困惑的是,我认为你需要一个长期存在的对象,以便拥有一个左值引用(我正在阅读 const std::string &
作为左值引用,也许我错了) .
为什么这行得通? "1234"
在我从函数 return 之后住在哪里?
第二个实现无效。
实际上 return "1234"
创建了一个驻留在堆栈上的临时(右值)字符串对象(就好像它是 return std::string("1234")
一样),一旦它 returns 返回的引用就变成了悬空引用,因为它在堆栈内存中。
最近的编译器会发出如下警告:
<source>: In function 'const string& get_ref()':
<source>:5:12: warning: returning reference to temporary [-Wreturn-local-addr]
5 | return "1234";
| ^~~~~~
std::string get_val()
{
return "1234";
}
在这种情况下,创建了一个字符串类型的对象,然后调用移动构造函数(通常会说复制,但由于编译器优化,更可能调用移动)以将值存储在目标变量中
const std::string & get_ref()
{
return "1234";
}
在这里你是return对临时本地对象的引用,所以当字符串的构造函数完成用“1234”构造字符串对象并且return被称为对象时之后被销毁,因为创建的对象在本地范围内是临时的。它应该向您抛出一个错误