Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why pass by const reference instead of by value?

Tags:

c++

function

From what I understand: when you pass by value, the function makes a local copy of the passed argument and uses that; when the function ends, it goes out of scope. When you pass by const reference, the function uses a reference to the passed argument that can't be modified. I don't understand, however, why one would choose one over the other, except in a situation where an argument needs to be modified and returned. If you had a void function where nothing is getting returned, why choose one over the other?

EDIT: So basically passing by const reference avoids copying the object. So in what situations is copying the object good? I mean, why not just use const references all the time if it optimizes performance all the time?

like image 820
Maulrus Avatar asked Apr 06 '10 05:04

Maulrus


People also ask

Why pass by reference is better than pass by value?

The main difference between pass by value and pass by reference is that, in a pass by value, the parameter value copies to another variable while, in a pass by reference, the actual parameter passes to the function.

Is pass by reference faster than pass by value?

What is surprising is that passing a complex object by reference is almost 40% faster than passing by value. Only ints and smaller objects should be passed by value, because it's cheaper to copy them than to take the dereferencing hit within the function.

Is it always better to pass by reference?

2) For passing large sized arguments: If an argument is large, passing by reference (or pointer) is more efficient because only an address is really passed, not the entire object.

Which is best pass by value or pass by reference?

Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself). Pass by value means the called functions' parameter will be a copy of the callers' passed argument.


1 Answers

There are two main considerations. One is the expense of copying the passed object and the second is the assumptions that the compiler can make when the object is a a local object.

E.g. In the first form, in the body of f it cannot be assumed that a and b don't reference the same object; so the value of a must be re-read after any write to b, just in case. In the second form, a cannot be changed via a write to b, as it is local to the function, so these re-reads are unnecessary.

void f(const Obj& a, Obj& b) {     // a and b could reference the same object }  void f(Obj a, Obj& b) {     // a is local, b cannot be a reference to a } 

E.g.: In the first example, the compiler may be able to assume that the value of a local object doesn't change when an unrelated call is made. Without information about h, the compiler may not know whether an object that that function has a reference to (via a reference parameter) isn't changed by h. For example, that object might be part of a global state which is modified by h.

void g(const Obj& a) {     // ...     h(); // the value of a might change     // ... }  void g(Obj a) {     // ...     h(); // the value of a is unlikely to change     // ... } 

Unfortunately, this example isn't cast iron. It is possible to write a class that, say, adds a pointer to itself to a global state object in its constructor, so that even a local object of class type might be altered by a global function call. Despite this, there are still potentially more opportunities for valid optimizations for local objects as they can't be aliased directly by references passed in, or other pre-existing objects.

Passing a parameter by const reference should be chosen where the semantics of references are actually required, or as a performance improvement only if the cost of potential aliasing would be outweighed by the expense of copying the parameter.

like image 125
CB Bailey Avatar answered Oct 18 '22 06:10

CB Bailey