简体   繁体   中英

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.

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.

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.

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.

Optional reading, carefully:

There's also a way of passing an argument as a raw pointer which is very rare in modern C++. Use with caution: 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) . 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 = . 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).

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".

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. Scalar arguments are of very small size, so they do not benefit from this approach.

See also Pass by Reference / Value in 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.

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.

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) )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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