Why pass by const reference instead of by value?

C++Function

C++ Problem Overview


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?

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

Passing arguments by value and thus copying them can be expensive - const references avoid that expensive step while still promising the caller that the object won't be changed.

Usually fundamental types (int, double, ...) are passed by value, while class-types are passed by const reference.

There can however be exceptions where pass-by-value for class-types can be beneficial.

Solution 3 - C++

Making a copy of an object could greatly affect the performance in some cases. Consider a function which argument will be std::vector<long> and you want to pass vector with 1 million elements. In this case you'll want to use const reference over passing by value. In this SO question you could find simple general rule for your question.

Solution 4 - C++

Sometimes, making a copy of an object can be expensive and so pass-by-const-reference will avoid having to make that copy. Otherwise, I would say that you should simply pass-by-value if that is what is semantically required.

Solution 5 - C++

To avoid making an unnecessary copy, thus improving performance.

Solution 6 - C++

Passing an argument by value has the overhead of a copy of the object being passed to the function.

Maybe an object isn't copyable and your choices are limited.

Solution 7 - C++

Because of the performance benefits you will get. Lets say you have a big object (in terms of size in bytes). Now, if you pass this object by value to a function a unnecessary copy needs to be created of this, however you can get the same effect by passing a const reference to that object itself without creating copy. Since a reference is normally stored as a pointer under the hoods, the cost of passing a reference is just sizeof(pointer).

Solution 8 - C++

An array can't be passed by value, so this is a good time to use a const pointer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMaulrusView Question on Stackoverflow
Solution 1 - C++CB BaileyView Answer on Stackoverflow
Solution 2 - C++Georg FritzscheView Answer on Stackoverflow
Solution 3 - C++Kirill V. LyadvinskyView Answer on Stackoverflow
Solution 4 - C++Dean HardingView Answer on Stackoverflow
Solution 5 - C++Paolo TedescoView Answer on Stackoverflow
Solution 6 - C++pmrView Answer on Stackoverflow
Solution 7 - C++NaveenView Answer on Stackoverflow
Solution 8 - C++Dovi SalomonView Answer on Stackoverflow