在函数的出口通过引用传递(=返回)一个向量
passing( = returning) by reference a vector at the exit of function
这段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。如果您担心复制它的成本,移动语义和/或省略将会解决这个问题。
相关文章:
- 如何返回向量的常量引用?
- 如何在C++中返回向量的从零开始的索引
- 当函数返回C++向量实例时,它正在运行
- 从函数返回向量以打印内容
- 返回向量的单个索引值
- 为什么我不能返回向量<向量<int>>(进程返回 -1073741819 (0xC0000005))
- 返回向量元素的 l 值的正确方法是什么?
- 为什么通过引用返回向量比通过移动返回要快得多?
- 返回向量 C++ 上的递归
- C++ std::find() 寻址返回向量的类函数时的意外行为
- 如何在返回向量中访问系数
- C++ 函数返回向量中最小的正整数
- 查找并将指针返回向量中的对象
- getCompatibleComponent返回向量错误
- 如何从 JNI 返回向量<向量<float>>?
- 为什么下面的代码返回向量大小为 10
- 从函数返回向量时C++中止(核心转储)
- 如何正确地将向量<int>转换为空隙*并返回向量<int>?
- 接口 PTR 的返回向量C++
- C++ cv::Mat 返回向量的<rectangle>线程异步