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

passing( = returning) by reference a vector at the exit of function

本文关键字:返回 向量 一个 出口 函数 引用      更新时间:2023-10-16

这段c++代码合法吗?

vector<myType>& aClass::aFunction()
{
    vector<myType> aVec;
    //do stuff
    return aVec;
}

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

vector<myType> getVec = aFunction();

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

不,它很淘气。不能返回对局部变量的引用。

按值返回。编译器应该为你做返回值优化,所以你不应该得到浪费的副本。

vector<myType> aClass::aFunction()
{
    vector<myType> aVec;
    // ...
    return aVec;
}

不可以,即使编译器会让它出错,变量也会随着函数的作用域而消失,所以你会有一个悬空引用,并有效地进入未定义行为状态。

按值返回,任何下降编译器将执行(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),并考虑添加适当的开关到编译器命令。例如:

g++ -Werror=return-local-addr ./dangling_reference.cpp
clang++ -Werror=return-stack-address ./dangling_reference.cpp

在我看来,如果你的项目足够大,不需要手工编译,这是一个很好的做法。

否-当函数返回时自动对象被销毁,使引用无效。对引用做任何操作都会产生未定义的行为。

你的编译器应该警告你这个;如果没有,那么就调高你的警告级别。

按值返回vector。如果您担心复制它的成本,移动语义和/或省略将会解决这个问题。