简体   繁体   English

我什么时候应该使用参考?

[英]When should I use a reference?

Newbie here, I am reading some code, and I see sometimes the author used the reference in a function as 新手在这里,我正在阅读一些代码,有时我看到作者在函数中使用了引用作为

funca (scalar& a)
// Etc

Sometimes he just use 有时候他只是用

funcb (scalar a)
// Etc

What's the difference? 有什么不同? Is using a reference a good habit that I should have? 使用参考是我应该养成的良好习惯吗?

Thank you! 谢谢!

If you call foo(scalar a) , the argument a of type scalar will be COPIED from the caller and foo will have it's own COPY of the original object. 如果调用foo(scalar a) ,则调用者将复制scalar类型的参数a ,而foo将拥有原始对象的COPY。

If you call foo(scalar &b) , the argument b will be just a reference to the original object, so you will be able to modify it. 如果调用foo(scalar &b) ,则参数b只是对原始对象的引用,因此您可以对其进行修改。

It's faster to pass an object by reference using the &name syntax, since it avoids creating a copy of the given object, but it can be potentially dangerous and sometimes the behavior is unwanted because you simply want an actual copy. 使用&name语法通过引用传递对象的速度更快,因为它避免了创建给定对象的副本,但是这样做可能具有潜在的危险,并且有时行为是不需要的,因为您只是想要一个实际的副本。

That being said, there's actually an option that disallows the ability to modify the original object for the called function yet avoids creating a copy. 话虽这么说,实际上有一个选项不允许修改被调用函数的原始对象,却避免创建副本。 It's foo(const scalar &x) which explicitly states that the caller does not want the function foo to modify the object passed as an argument. 它是foo(const scalar &x) ,它明确指出调用者不希望函数foo修改作为参数传递的对象。

Optional reading, carefully: 可选阅读,请仔细:

There's also a way of passing an argument as a raw pointer which is very rare in modern C++. 还有一种将参数作为原始指针传递的方法,这在现代C ++中非常罕见。 Use with caution: foo(scalar *a) . 请谨慎使用: foo(scalar *a) The caller has got to provide the address of an object instead of the object itself in this scenario, so the caller would call foo(&a) . 在这种情况下,调用者必须提供对象的地址,而不是对象本身,因此调用者将调用foo(&a) For the called function foo to be able to modify the object itself in this case, it would need to dereference the pointer a , like this in foo : *a = . 为了使被调用的函数foo在这种情况下能够修改对象本身,将需要取消引用指针a ,就像在foo*a = The star in front of the variable name in this case says that we don't want to modify the address that we have received (as a direct result of the calling function providing &a , that is, the address of the object a). 在这种情况下,变量名前面的星号表示我们不想修改已收到的地址(作为调用函数提供&a的直接结果,即对象a的地址)。

Passing a parameter by reference allows the called function to modify its argument in a way that will be visible to the caller after the function returns, while passing by value means that any changes will be limited in scope to the called function. 通过引用传递参数允许被调用函数以在函数返回后对调用者可见的方式修改其参数,而按值传递意味着任何更改都将在范围上限制于被调用函数。 Therefore passing by (non-const) reference typically signifies that the callee intends to modify the argument or, less commonly, use it as an additional "return value". 因此,传递(非const)引用通常表示被调用方打算修改自变量,或者(较不常见)将其用作附加的“返回值”。

Additionally, passing by reference means that no copy of the parameter needs to be made; 另外,通过引用传递意味着不需要复制参数。 passing by value requires such a copy (which may be detrimental for the memory footprint or runtime performance of your application). 按值传递需要这样的副本(这可能对应用程序的内存占用或运行时性能有害)。 For this reason you will often see arguments of class type being passed as a const reference: the callee does not intend to modify the argument but it also wants to avoid a copy being made. 出于这个原因,您经常会看到类类型的参数作为const引用传递:被调用者无意修改参数,但也希望避免进行复制。 Scalar arguments are of very small size, so they do not benefit from this approach. 标量参数的大小很小,因此它们不能从这种方法中受益。

See also Pass by Reference / Value in C++ . 另请参见C ++中的按引用/值传递

Call by value ( funcb (scalar a) ) will give the function a copy of the argument, so changes made to the argument are not visible to the caller. 按值调用( funcb (scalar a) )将为函数提供参数的副本,因此对参数的更改对调用者不可见。

Call by reference ( funcb(scalar& b) ) means that the function operates directly on the argument, so any changes made are directly visible to the caller. 通过引用调用( funcb(scalar& b) )意味着该函数直接对参数进行操作,因此所做的任何更改对调用者都是直接可见的。

Whether or not call by reference is a good practice depends on the circumstances. 通过引用进行呼叫是否是一种良好做法,取决于情况。 If you need the function to modify the argument (and the modifications to be visible to the caller) you obviously want to use call by reference. 如果您需要该函数来修改自变量(以及对调用者可见的修改),则显然要使用按引用调用。 If you don't want to modify the argument using non-const reference arguments is misleading (since the signature indicates the argument could be changed), so call by value is more apropriate here. 如果您不想使用非常量引用参数来修改参数,则会引起误解(因为签名表明可以更改参数),因此按值调用在此处更为合适。 Of course for more complex types call by value can have a non-trivial overhead. 当然,对于更复杂的类型,按值调用可能会产生不小的开销。 In these cases call-by-const-reference is preferable ( funcc(const scalar& c) ) 在这些情况下,最好使用按常量引用调用( funcc(const scalar& c)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM