简体   繁体   中英

Difference between reference and const reference as function parameter?

Here is a simple snippet of C++ code:

A foo(){
  A a; // create a local A object
  return a;
}

void bar(const A & a_r){

}

bar(foo());

Why does the argument of function bar have to be a const reference,not just a reference?

Edit1: I know that reference is to avoid copying overhead. and const is for read-only. But here I have to make it a const reference, otherwise if I remove the "const", g++ will throw an error to me.

Edit2: My guess is that the return object of foo() is a temporary object, and it's not allowed to change the value of a temporary object ?

Without the error message, I'm not exactly sure what the compiler might be complaining about, but I can explain the reason logically:

In the line:

bar(foo()); 

The return value of foo() is a temporary A; it is created by the call to foo(), and then destructed as soon as bar() returns. Performing a non-const operation (ie an operation that changes the temporary A) doesn't make sense, as the object A is destructed right afterwards.

Looking a little more, this is a virtual dup of this question:

How come a non-const reference cannot bind to a temporary object?

which has an excellent answer.

The reference has to refer to const object because you won't be able to utilize changes to it anyway. Compare the following code snippets:

void bar(A&);   
A x = foo();
bar(x);
if (x.member) {...} else {...}

and

void bar(A const&);   
bar(foo());
if (//x? we don't have any x! We can't branch here!

While in the first example, the ability to modify the object may significantly alter the execution of the consequent code, in the second one we just don't have the means (variable name we could refer to) to do it. Therefore, we can only use the reference to const, which wants the object to be not modified.

Why does the argument of function bar have to be a const reference,not just a reference?

The argument of bar() need not be const reference. But when passing objects to function parameter, it is the most efficient way when the object will not be modified by the function.

  • Making a parameter constant guarantees that the compiler wil issue warning when you try to modify the object.
  • Passing a parameter as reference will not create a copy of the object and hence efficiency is achieved.

Compiler is looking for bar(const foo&) because you are passing const reference to foo into bar in bar(foo()) - this is because you are passing reference to a temporary variable which will not exist once bar returns .

There is no use case where it makes sense to modify foo inside bar via the reference because it will not exist once you return from bar().

So compiler enforces this to prevent hiden bugs where developer passes reference to temporary and updates the temporary object which will disappear after method returns.

the code bar(foo()) is passing a lvalue to bar(). only rvalue can have a pointer or reference to it. lvalue can have a const reference to it because the const restriction prevent an assignment operation to a non-existing lvalue.

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