通过引用函数出口处的向量传递(=返回)

时间:2014-05-13 00:08:34

标签: c++ function return-value pass-by-reference

这个c ++ snipet合法吗?

vector<myType>& aClass::aFunction()
{
    vector<myType> aVec;

    //do stuff

    return aVec;
}

然后在另一个函数中使用它:

vector<myType> getVec = aFunction();

所以基本上,我问:如果我宣布getVec并获得对aVec矢量数据的引用,数据是否会在aFunction()死亡后存活?

3 个答案:

答案 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,如果您的项目足够大,除了手工编译之外,这是一个很好的做法。