这个c ++ snipet合法吗?
vector<myType>& aClass::aFunction()
{
vector<myType> aVec;
//do stuff
return aVec;
}
然后在另一个函数中使用它:
vector<myType> getVec = aFunction();
所以基本上,我问:如果我宣布getVec
并获得对aVec
矢量数据的引用,数据是否会在aFunction()
死亡后存活?
答案 0 :(得分:3)
不,这很顽皮。您不能返回对局部变量的引用。
按价值将其传回去。编译器应该为您进行返回值优化,因此您不应该浪费副本。
vector<myType> aClass::aFunction()
{
vector<myType> aVec;
// ...
return aVec;
}
答案 1 :(得分:2)
否 - 当函数返回时,自动对象被销毁,使引用无效。对引用执行任何操作都会产生未定义的行为。
你的编译器应该警告你这件事;如果它没有,那么请调高警告级别。
按值返回向量。如果您担心复制它的成本,移动语义和/或省略将会解决这个问题。
答案 2 :(得分:2)
即使编译器不让它滑动,变量也会在函数范围内消失,因此您将有一个悬空引用并有效地进入未定义行为状态。
按值返回,任何下降编译器都将执行(N)RVO。有一些限制,因此您应该全面检查编译器的要求。特别是如果有多个出口点。但它是最好的行动方案,可以生成最干净,最快的代码。
附录:
确实会在clang++
和g++
上生成(“仅”)警告:
luk32@debianvm:~/projects/tests$ g++ ./dangling_reference.cpp
./dangling_reference.cpp: In function 'std::vector<int>& test()':
./dangling_reference.cpp:6:17: warning: reference to local variable 'v' returned [-Wreturn-local-addr]
vector<int> v(10);
^
luk32@debianvm:~/projects/tests$ clang++ ./dangling_reference.cpp
./dangling_reference.cpp:7:12: warning: reference to stack memory associated with local variable 'v' returned [-Wreturn-stack-address]
return v;
但是我建议将这些警告标记为错误,因为它们几乎总是(几乎我的意思是安全方面,我不知道如何返回对局部变量的引用而不进入UB),并考虑在编译器命令中添加适当的开关。 E.g:
g++ -Werror=return-local-addr ./dangling_reference.cpp
clang++ -Werror=return-stack-address ./dangling_reference.cpp
IMO,如果您的项目足够大,除了手工编译之外,这是一个很好的做法。