C++ 返回值、引用、常量引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21778045/
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
C++ Return value, reference, const reference
提问by Majak
Can you explain to me the difference between returning value, reference to value, and const reference to value?
你能向我解释一下返回值、引用值和常量引用值之间的区别吗?
Value:
价值:
Vector2D operator += (const Vector2D& vector)
{
this->x += vector.x;
this->y += vector.y;
return *this;
}
Not-const reference:
非常量参考:
Vector2D& operator += (const Vector2D& vector)
{
this->x += vector.x;
this->y += vector.y;
return *this;
}
Const reference:
常量参考:
const Vector2D& operator += (const Vector2D& vector)
{
this->x += vector.x;
this->y += vector.y;
return *this;
}
What is the benefit of this? I understand the sense behind const reference passing to function as you want to make sure not to modify this value on which reference is pointing to inside a the function. But I'm confused by the meaning of returning const reference. Why returning of reference is better than returning of value, and why returning of const reference is better than returning of not-const reference?
这有什么好处?我理解传递给函数的 const 引用背后的意义,因为您想确保不要修改引用指向函数内部的这个值。但是我对返回 const 引用的含义感到困惑。为什么返回引用比返回值好,为什么返回const引用比返回not-const引用好?
采纳答案by Mike Seymour
There is no difference unless you write something weird like
除非你写一些奇怪的东西,否则没有区别
(v1 += v2) = v3;
In the first case, the assignment will be to a temporary, and the overall effect will be v1 += v2
.
在第一种情况下,分配将是临时的,整体效果将是v1 += v2
。
In the second case, the assignment will be to v1
, so the overall effect will be v1 = v3
.
在第二种情况下,分配将是v1
,因此整体效果将是v1 = v3
。
In the third case, the assignment won't be allowed. This is probably the best option, since such weirdness is almost certainly a mistake.
在第三种情况下,将不允许分配。这可能是最好的选择,因为这种怪异几乎肯定是错误的。
Why returning of reference is better than returning of value?
为什么返回引用比返回值更好?
It's potentially more efficient: you don't have to make a copy of the object.
它可能更有效:您不必制作对象的副本。
and why returning of const reference is better than returning of not-const reference?
为什么返回const 引用比返回not-const 引用更好?
You prevent weirdness like the above example, while still allowing less weird chaining such as
你可以防止像上面的例子那样奇怪,同时仍然允许不那么奇怪的链接,比如
v1 = (v2 += v3);
But, as noted in the comments, it means that your type doesn't support the same forms of (ab)use as the built-in types, which some people consider desirable.
但是,正如评论中所指出的,这意味着您的类型不支持与内置类型相同的 (ab) 使用形式,有些人认为这是可取的。
回答by Tomek
Value:
价值:
Returning by value means that you are returning a copy of an object. This puts requirements on the class (it has to be copyable or moveable). This means that for object of some classes returning by value may be expensive (in a case where RVO or NRVO does not work or is switched off). This also means that the new object is independent (subject to its design) from other objects and is a value of its own. This is what you probably should return from many binary operators like +, -, * and so on.
按值返回意味着您正在返回对象的副本。这对类提出了要求(它必须是可复制或可移动的)。这意味着对于某些类的对象,按值返回可能会很昂贵(在 RVO 或 NRVO 不起作用或关闭的情况下)。这也意味着新对象独立于其他对象(受其设计影响)并且是它自己的值。这是您可能应该从许多二元运算符(如 +、-、* 等)返回的内容。
Non-const reference:
非常量参考:
You really return an alias for another object. The alias being non const allow you to modify aliased object. This is what you should return from some unary oprators like prefix ++ and --, and * (dereference) as you usually want to have the ability to modify returned object.
你真的为另一个对象返回了一个别名。非 const 别名允许您修改别名对象。这是您应该从一些一元运算符返回的内容,例如前缀 ++ 和 -- 以及 *(取消引用),因为您通常希望能够修改返回的对象。
This is returned by operator>> and operator<< overloaded for streams. This allows chaining of operators:
这由为流重载的 operator>> 和 operator<< 返回。这允许链接运算符:
cout << 5 << "is greater then" << 1 << endl;
cin >> myInt >> myFloat;
You can also return reference to *this when you want to allow chaining of regular methods like this:
当您希望允许像这样链接常规方法时,您还可以返回对 *this 的引用:
object.run().printLastRunStatistics();
Const reference:
常量参考:
Like above but you CANNOT modify aliased object. May be used instead of returning by value when the object to be returned is expensive to copy and when you can ensure its existence after you return from a function.
像上面一样,但你不能修改别名对象。当要返回的对象复制成本很高并且在从函数返回后可以确保其存在时,可以使用而不是按值返回。
This is what operator= usually returns to allow multiple assignments in a way standard types support them:
这就是 operator= 通常返回的内容,以允许以标准类型支持的方式进行多次赋值:
a = b = c;
Const-reference used in operator= prevents this kind of usage (not supported by standard type as far as I remember):
在 operator= 中使用的常量引用可防止这种用法(据我所知,标准类型不支持):
++(a = b);
which would be allowed if normal reference was used.
如果使用正常参考,这将是允许的。
回答by barak manos
The difference between return-by-valueand return-by-referencetakes effect during run-time:
之间的差值回报按值和返回按引用需要在运行时间期间的效果:
When you return an object by-value, the copy-constructor is called, and a temporary instance is created on the stack.
当您按值返回对象时,将调用复制构造函数,并在堆栈上创建一个临时实例。
When you return an object by-reference, all the above does not take place, leading to improved performance.
当您通过引用返回对象时,上述所有情况都不会发生,从而提高性能。
The difference between return-by-referenceand return-by-constant-referencehas no run-time effect, and is simply there to protect you from writing erroneous code.
之间的差额收益按参考,并返回由常数引用没有运行时的效果,简直是为了保护你从编写错误代码。
For example, with Vector2D& operator += (const Vector2D& vector)
, you can do:
例如,使用Vector2D& operator += (const Vector2D& vector)
,您可以执行以下操作:
(x+=y)++
or (x+=y).func()
where func
is a non-const function in class Vector2D
.
(x+=y)++
或(x+=y).func()
wherefunc
是 class 中的非常量函数Vector2D
。
But with const Vector2D& operator += (const Vector2D& vector)
, the compiler will generate an error for any such similar attempt.
但是const Vector2D& operator += (const Vector2D& vector)
,对于任何此类类似的尝试,编译器都会生成错误。
回答by luk32
It is exactly the same as passing argument to the function.
它与向函数传递参数完全相同。
You want to return a const
reference when you return a property of an object, that you want not to be modified out-side of it. For example: when your object has a name, you can make following method const std::string& get_name(){ return name; };
. Which is most optimal way. You allow a "read-only" access to an internal property, with out copy-on-return.
const
当您返回一个对象的属性时,您希望返回一个引用,您不想在它之外修改该属性。例如:当您的对象有名称时,您可以使用以下方法const std::string& get_name(){ return name; };
。这是最优化的方式。您允许对内部属性进行“只读”访问,而无需复制返回。
When you are overloading operators you are expected to return an object that is mutable, otherwise some certain syntax that is usually expected to work will produce errors. It is quite important when you try some weird chaining.
当您重载运算符时,您应该返回一个可变的对象,否则某些通常预期有效的语法会产生错误。当您尝试一些奇怪的链接时,这非常重要。
For example option 3 will not work with something like (v1 += v2).non_const_method()
, While, the following would:
例如,选项 3 不适用于类似(v1 += v2).non_const_method()
, While 之类的内容,以下内容将:
v1+=v2;
v1.non_const_method();
回答by 51k
As pointed out but luk32 it is just to ensure that no changes are allowed to the objects returned by this function. This can basically help you in finding your logical errors at compile time. Suppose you are sure not to change a object, and your code is changing the object, it can be tracked. It can be thought of a good coding practice.
正如所指出的,luk32 只是为了确保不允许对此函数返回的对象进行更改。这基本上可以帮助您在编译时找到逻辑错误。假设您确定不更改对象,并且您的代码正在更改对象,则可以对其进行跟踪。它可以被认为是一种很好的编码习惯。