C++ 中的函数是按值返回还是按引用返回?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7456778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Function in C++ returns by value or by reference?
提问by smilingbuddha
When a function (callee) returns a quantity to the caller function, is it returned by value or by reference?
当一个函数(被调用者)向调用者函数返回一个数量时,是按值返回还是按引用返回?
The thing is I have written a function which builds a very large vector of when called. I want to returnthis big vector to the calling function , ( in this case main()
) by constant reference so I can do some further processing on it.
问题是我写了一个函数,它构建了一个非常大的调用向量。我想通过常量引用将这个大向量返回给调用函数(在这种情况下main()
),以便我可以对它做一些进一步的处理。
I was in doubt because I was told that when a C++ function returns and terminates, all the variables/memory associated with that function, get wiped clean.
我对此表示怀疑,因为有人告诉我,当 C++ 函数返回并终止时,与该函数关联的所有变量/内存都会被清除。
struct node{
string key;
int pnum;
node* ptr;
}
vector< vector<node> > myfun1(/*Some arguments*/)
{
/*Build the vector of vectors. Call it V*/
return v;
}
int main(void)
{
a=myfun1(/* Some arguments */)
}
回答by Ben Voigt
C++ functions can return by value, by reference (but don't return a local variable by reference), or by pointer (again, don't return a local by pointer).
C++ 函数可以通过值、通过引用(但不要通过引用返回局部变量)或通过指针(同样,不要通过指针返回局部变量)返回。
When returning by value, the compiler can often do optimizations that make it equally as fast as returning by reference, without the problem of dangling references. These optimizations are commonly called "Return Value Optimization (RVO)" and/or "Named Return Value Optimization (NRVO)".
当按值返回时,编译器通常可以进行优化,使其与按引用返回一样快,而不会出现悬空引用的问题。这些优化通常称为“返回值优化 (RVO)”和/或“命名返回值优化 (NRVO)”。
Another way to for the caller to provide an empty vector (by reference), and have the function fill it in. Then it doesn't need to return anything.
另一种方法是调用者提供一个空向量(通过引用),并让函数填充它。然后它不需要返回任何东西。
You definitely should read this blog posting: Want Speed? Pass by value.
您绝对应该阅读这篇博文:想要速度吗?按值传递。
回答by paercebal
By default, everything in C/C++ is passed by value, including return type, as in the example below:
默认情况下,C/C++ 中的所有内容都是按值传递的,包括返回类型,如下例所示:
T foo() ;
In C++, where the types are usually considered value-types (i.e. they behave like int
or double
types), the extra copy can be costly if the object's construction/destruction is not trivial.
在 C++ 中,类型通常被认为是值类型(即它们的行为类似于int
或double
类型),如果对象的构造/销毁不是微不足道的,则额外的副本可能会很昂贵。
With C++03
使用 C++03
If you want to return by reference, or by pointer, you need to change the return type to either:
如果要通过引用或指针返回,则需要将返回类型更改为:
T & foo() ; // return a reference
T * foo() ; // return a pointer
but in both cases, you need to make sure the object returned still exists after the return. For example, if the object returned was allocated on stack in the body of the function, the object will be destroyed, and thus, its reference/pointer will be invalid.
但是在这两种情况下,您都需要确保 return 之后返回的对象仍然存在。例如,如果返回的对象在函数体的堆栈上分配,则该对象将被销毁,因此其引用/指针将无效。
If you can't guarantee the object still exists after the return, your only solution is to either:
如果您不能保证返回后对象仍然存在,您唯一的解决方案是:
- accept the cost of an extra copy, and hope for a Return Value Optimization
- pass instead a variable by reference as a parameter to the function, as in the following:
- 接受额外副本的成本,并希望进行返回值优化
- 而是通过引用将变量作为参数传递给函数,如下所示:
void foo(T & t) ;
void foo(T & t) ;
This way, inside the function, you set the t
value as necessary, and after the function returns, you have your result.
这样,在函数内部,您可以t
根据需要设置值,在函数返回后,您就会得到结果。
With C++11
使用 C++11
Now, if you have the chance to work with C++0x/C++11, that is, with a compiler that supports r-values references/move semantics, if your object has the right constructor/operator (if your object comes from the standard library, then it's ok), then the extra temporary copy will be optimized away, and you can keep the notation:
现在,如果您有机会使用 C++0x/C++11,即使用支持右值引用/移动语义的编译器,如果您的对象具有正确的构造函数/运算符(如果您的对象来自来自标准库,然后就可以了),那么额外的临时副本将被优化掉,您可以保留符号:
T foo() ;
Knowing that the compiler will not generate an unnecessary temporary value.
知道编译器不会生成不必要的临时值。
回答by SoapBox
C++ can return either by reference or by value. If you want to return a reference, you must specify that as part of the return type:
C++ 可以按引用或按值返回。如果要返回引用,则必须将其指定为返回类型的一部分:
std::vector<int> my_func(); // returns value
std::vector<int>& my_func(); // returns reference
std::vector<int> const& my_func(); // returns constant reference
All local (stack) variables created inside of a function are destroyed when the function returns. That means you should absolutely not return locals by reference or const reference (or pointers to them). If you return the vector by value it maybe copied before the local is destroyed, which could be costly. (Certain types of optimizations called "return value optimization" can sometimes remove the copy, but that's out of the scope of this question. It's not always easy to tell whether the optimization will happen on a particular piece of code.)
当函数返回时,在函数内部创建的所有局部(堆栈)变量都会被销毁。这意味着您绝对不应该通过引用或常量引用(或指向它们的指针)返回局部变量。如果您按值返回向量,它可能会在本地被销毁之前被复制,这可能会很昂贵。(称为“返回值优化”的某些类型的优化有时可以删除副本,但这超出了本问题的范围。判断优化是否会发生在特定代码段上并不总是那么容易。)
If you want to "create" a large vector inside of a function and then return it without copying, the easiest way is to pass the vector in to the function as a reference parameter:
如果要在函数内部“创建”一个大向量,然后不复制就返回它,最简单的方法是将向量作为引用参数传递给函数:
void fill_vector(std::vector<int> &vec) {
// fill "vec" and don't return anything...
}
Also note that in the recently ratified new version of the C++ standard (known as C++0x or C++11) returning a local vector by value from a function will notactually copy the vector, it will be efficiently movedinto its new location. The code that does this looks identicalto code from previous versions of C++ which could be forced to copy the vector. Check with your compiler to see whether it supports "move semantics" (the portion of the C++11 standard that makes this possible).
另请注意,在最近批准的 C++ 标准(称为 C++0x 或 C++11)的新版本中,按值从函数返回本地向量实际上不会复制该向量,而是将其有效地移动到新版本中地点。执行此操作的代码看起来与C++ 以前版本中的代码相同,后者可能会被强制复制向量。检查您的编译器是否支持“移动语义”(C++11 标准中使这成为可能的部分)。
回答by timday
It's returned by whatever you declare the return type to be. vector<int> f();
and vector<int>& f();
return by value and reference respectively. However, it would be a grave error to return a reference to a local variable in the function as it will have been blown away when the function scope exits.
它由您声明的返回类型返回。 vector<int> f();
并vector<int>& f();
分别按值和引用返回。但是,在函数中返回对局部变量的引用将是一个严重的错误,因为它会在函数作用域退出时被吹走。
For good tips on how to efficiently return large vectors from a function, see this question(in fact this one is arguably a duplicate of that).
回答by K-ballo
The function will return what you tell it to return. If you want to return a vector
, then it will be copied to the variable hold by the caller. Unless you capture that result by const reference, in which case there is no need to copy it. There are optimizations that allow functions to avoid this extra copy-constructon by placing the result in the object that will hold the return value. You should read this before changing your design for performance:
该函数将返回您告诉它返回的内容。如果您想返回 a vector
,那么它将被调用者复制到变量hold 中。除非您通过常量引用捕获该结果,否则无需复制它。有一些优化允许函数通过将结果放在将保存返回值的对象中来避免这种额外的复制构造。在更改性能设计之前,您应该阅读以下内容:
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
回答by Zack Yezek
Like most things in C++, the answer is "it depends on how you defined the function".
与 C++ 中的大多数事情一样,答案是“这取决于您如何定义函数”。
The default for the language is return-by-value. A simple call like "double f()" is going to always return the floating-point number by value. However, you CAN return values by pointer or by reference- you just add the extra symbols '&' or '*' to the return type:
该语言的默认值是按值返回。像“double f()”这样的简单调用将始终按值返回浮点数。但是,您可以通过指针或引用返回值——您只需在返回类型中添加额外的符号“&”或“*”:
// Return by pointer (*)
T* f();
// Return by reference (a single '&')
T& f();
However, these are ridiculously unsafe in many situations. If the value the function is returning was declared within the function, the returned reference or pointer will point to random garbage instead of valid data. Even if you can guarantee that the pointed-to data is still around, this kind of return is usually more trouble than it is worth given the optimizations all modern C++ compilers will do for you. The idiomatic, safe way to return something by reference is to pass a named reference in as a parameter:
然而,在许多情况下,这些都是非常不安全的。如果函数返回的值是在函数内声明的,则返回的引用或指针将指向随机垃圾而不是有效数据。即使您可以保证指向的数据仍然存在,考虑到所有现代 C++ 编译器都会为您做的优化,这种返回通常比值得的麻烦更多。通过引用返回某些东西的惯用的、安全的方法是将命名引用作为参数传入:
// Return by 'parameter' (a logical reference return)
void f(T& output);
Now the output has a real name, and we KNOW it will survive the call because it has to exist before the call to 'f' is even made. This is a pattern you will see often in C++, especially for things like populating a STL std::vector. Its ugly, but until the advent of C++11 it was often faster than simply returning the vector by value. Now that return by value is both simpler and faster even for many complex types, you will probably not see many functions following the reference return parameter pattern outside of older libraries.
现在输出有一个真实的名字,我们知道它会在调用中幸存下来,因为它必须在调用 'f' 之前就存在。这是您在 C++ 中经常会看到的一种模式,尤其是对于填充 STL std::vector 之类的事情。它很难看,但在 C++11 出现之前,它通常比简单地按值返回向量要快。现在,即使对于许多复杂类型,按值返回既简单又快捷,您可能不会在旧库之外看到许多遵循引用返回参数模式的函数。
回答by nulvinge
All variables defined on the stack are cleaned upon exit. To return a variable you should allocate it on the heap, which you do with the new keyword (or malloc).
堆栈上定义的所有变量在退出时都会被清除。要返回一个变量,你应该在堆上分配它,你用 new 关键字(或 malloc)来做。
Classes and structs are passed around as pointers, while the primitive types are passed around as values.
类和结构作为指针传递,而基本类型作为值传递。