Related
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?
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.
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.
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.
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.
To avoid making an unnecessary copy, thus improving performance.
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.
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).
An array can't be passed by value, so this is a good time to use a const pointer.
Is it better in C++ to pass by value or pass by reference-to-const?
I am wondering which is better practice. I realize that pass by reference-to-const should provide for better performance in the program because you are not making a copy of the variable.
It used to be generally recommended best practice1 to use pass by const ref for all types, except for builtin types (char, int, double, etc.), for iterators and for function objects (lambdas, classes deriving from std::*_function).
This was especially true before the existence of move semantics. The reason is simple: if you passed by value, a copy of the object had to be made and, except for very small objects, this is always more expensive than passing a reference.
With C++11, we have gained move semantics. In a nutshell, move semantics permit that, in some cases, an object can be passed “by value” without copying it. In particular, this is the case when the object that you are passing is an rvalue.
In itself, moving an object is still at least as expensive as passing by reference. However, in many cases a function will internally copy an object anyway — i.e. it will take ownership of the argument.2
In these situations we have the following (simplified) trade-off:
We can pass the object by reference, then copy internally.
We can pass the object by value.
“Pass by value” still causes the object to be copied, unless the object is an rvalue. In the case of an rvalue, the object can be moved instead, so that the second case is suddenly no longer “copy, then move” but “move, then (potentially) move again”.
For large objects that implement proper move constructors (such as vectors, strings …), the second case is then vastly more efficient than the first. Therefore, it is recommended to use pass by value if the function takes ownership of the argument, and if the object type supports efficient moving.
A historical note:
In fact, any modern compiler should be able to figure out when passing by value is expensive, and implicitly convert the call to use a const ref if possible.
In theory. In practice, compilers can’t always change this without breaking the function’s binary interface. In some special cases (when the function is inlined) the copy will actually be elided if the compiler can figure out that the original object won’t be changed through the actions in the function.
But in general the compiler can’t determine this, and the advent of move semantics in C++ has made this optimisation much less relevant.
1 E.g. in Scott Meyers, Effective C++.
2 This is especially often true for object constructors, which may take arguments and store them internally to be part of the constructed object’s state.
Edit: New article by Dave Abrahams on cpp-next: Want speed? Pass by value.
Pass by value for structs where the copying is cheap has the additional advantage that the compiler may assume that the objects don't alias (are not the same objects). Using pass-by-reference the compiler cannot assume that always. Simple example:
foo * f;
void bar(foo g) {
g.i = 10;
f->i = 2;
g.i += 5;
}
the compiler can optimize it into
g.i = 15;
f->i = 2;
since it knows that f and g doesn't share the same location. if g was a reference (foo &), the compiler couldn't have assumed that. since g.i could then be aliased by f->i and have to have a value of 7. so the compiler would have to re-fetch the new value of g.i from memory.
For more pratical rules, here is a good set of rules found in Move Constructors article (highly recommended reading).
If the function intends to change the argument as a side effect, take it by non-const reference.
If the function doesn't modify its argument and the argument is of primitive type, take it by value.
Otherwise take it by const reference, except in the following cases
If the function would then need to make a copy of the const reference anyway, take it by value.
"Primitive" above means basically small data types that are a few bytes long and aren't polymorphic (iterators, function objects, etc...) or expensive to copy. In that paper, there is one other rule. The idea is that sometimes one wants to make a copy (in case the argument can't be modified), and sometimes one doesn't want (in case one wants to use the argument itself in the function if the argument was a temporary anyway, for example). The paper explains in detail how that can be done. In C++1x that technique can be used natively with language support. Until then, i would go with the above rules.
Examples: To make a string uppercase and return the uppercase version, one should always pass by value: One has to take a copy of it anyway (one couldn't change the const reference directly) - so better make it as transparent as possible to the caller and make that copy early so that the caller can optimize as much as possible - as detailed in that paper:
my::string uppercase(my::string s) { /* change s and return it */ }
However, if you don't need to change the parameter anyway, take it by reference to const:
bool all_uppercase(my::string const& s) {
/* check to see whether any character is uppercase */
}
However, if you the purpose of the parameter is to write something into the argument, then pass it by non-const reference
bool try_parse(T text, my::string &out) {
/* try to parse, write result into out */
}
Depends on the type. You are adding the small overhead of having to make a reference and dereference. For types with a size equal or smaller than pointers that are using the default copy ctor, it would probably be faster to pass by value.
As it has been pointed out, it depends on the type. For built-in data types, it is best to pass by value. Even some very small structures, such as a pair of ints can perform better by passing by value.
Here is an example, assume you have an integer value and you want pass it to another routine. If that value has been optimized to be stored in a register, then if you want to pass it be reference, it first must be stored in memory and then a pointer to that memory placed on the stack to perform the call. If it was being passed by value, all that is required is the register pushed onto the stack. (The details are a bit more complicated than that given different calling systems and CPUs).
If you are doing template programming, you are usually forced to always pass by const ref since you don't know the types being passed in. Passing penalties for passing something bad by value are much worse than the penalties of passing a built-in type by const ref.
This is what i normally work by when designing the interface of a non-template function:
Pass by value if the function does not want to modify the parameter and the
value is cheap to copy (int, double, float, char, bool, etc... Notice that std::string, std::vector, and the rest of the containers in the standard library are NOT)
Pass by const pointer if the value is expensive to copy and the function does
not want to modify the value pointed to and NULL is a value that the function handles.
Pass by non-const pointer if the value is expensive to copy and the function
wants to modify the value pointed to and NULL is a value that the function handles.
Pass by const reference when the value is expensive to copy and the function does not want to modify the value referred to and NULL would not be a valid value if a pointer was used instead.
Pass by non-const reference when the value is expensive to copy and the function wants to modify the value referred to and NULL would not be a valid value if a pointer was used instead.
Sounds like you got your answer. Passing by value is expensive, but gives you a copy to work with if you need it.
As a rule passing by const reference is better.
But if you need to modify you function argument locally you should better use passing by value.
For some basic types the performance in general the same both for passing by value and by reference. Actually reference internally represented by pointer, that is why you can expect for instance that for pointer both passing are the same in terms of performance, or even passing by value can be faster because of needless dereference.
Pass by value for small types.
Pass by const references for big types (the definition of big can vary between machines) BUT, in C++11, pass by value if you are going to consume the data, since you can exploit move semantics. For example:
class Person {
public:
Person(std::string name) : name_(std::move(name)) {}
private:
std::string name_;
};
Now the calling code would do:
Person p(std::string("Albert"));
And only one object would be created and moved directly into member name_ in class Person. If you pass by const reference, a copy will have to be made for putting it into name_.
As a rule of thumb, value for non-class types and const reference for classes.
If a class is really small it's probably better to pass by value, but the difference is minimal. What you really want to avoid is passing some gigantic class by value and having it all duplicated - this will make a huge difference if you're passing, say, a std::vector with quite a few elements in it.
Pass by referece is better than pass by value. I was solving the longest common subsequence problem on Leetcode. It was showing TLE for pass by value but accepted the code for pass by reference. Took me 30 mins to figure this out.
Simple difference :- In function we have input and output parameter , so if your passing input and out parameter is same then use call by reference else if input and output parameter are different then better to use call by value .
example void amount(int account , int deposit , int total )
input parameter : account , deposit
output paramteter: total
input and out is different use call by vaule
void amount(int total , int deposit )
input total deposit
output total
This question already has answers here:
Is it better in C++ to pass by value or pass by reference-to-const?
(11 answers)
Closed 9 years ago.
I am always in a doubt on when I should reference and when I should use a variable pass.
For example, one of the API is called by the JOBJECTs -
QLIST retrive_cinemas(QString& options)
{
return (staticobject::getcinemas(options));
}
or
QLIST retrive_cinemas(QString options)
{
return (staticobject::getcinemas(options));
}
It seems to me that your problem can be reduced to something like this:
You have a function/method f(), and a class X, and you want to
know if/when X should be passed to f() by reference or not.
You can identify three options:
void f(X v) // #1 - pass by value
void f(const X& cr) // #2 - pass by const reference (&)
void f(X& r) // #3 - pass by reference (&)
If X is cheap to copy (e.g. it's an int, a double, etc.),
and you do not want to modify it, then pass by value (#1).
If X is not cheap to copy (e.g. it's a vector, a string,
etc.), and yo do not want to modify it, then pass by const
reference (#2).
If you want to modify the argument of type X inside f(), then
pass by reference.
In the particular code you posted, since QString is a full-fledged class which is not cheap to copy as e.g. an int or a double (even if it uses COW techniques and "implicit sharing", I believe that copying still implies a call to something like Win32 InterlockedIncrement() for increasing the ref count in a thread-safe atomic way), I'd pass it by const reference (i.e. const QString &, #2) if you do not want to modify it inside the function.
Just pass by reference (QString&, #3) if you want to modify it inside the function's body.
In Qt the answer depends on whether the object you would like to pass uses implicit sharing or not:
Many C++ classes in Qt use implicit data sharing to maximize resource
usage and minimize copying. Implicitly shared classes are both safe
and efficient when passed as arguments, because only a pointer to the
data is passed around, and the data is copied only if and when a
function writes to it, i.e., copy-on-write.
You can but you need not pass objects using implicit sharing by reference. They are designed to be passed by value efficiently!
Here you can find the complete explanation and the list of classes using implicit sharing. QString uses implicit sharing.
In Qt strings are implicitly shared and automatically copied on edit, so they are safe to pass even by value. It is still good practice to pass by reference though (in case it is not a QString), and it is even a tiny bit more efficient, since less data is copied, one memory address vs memory address, size and reference counting.
Generally speaking, it is a good idea to pass by reference when you want to modify the actual object inside the function (note that if you pass implicitly shared QString by value and modify it inside the function, this will not modify the original string but copy it and the changes will be lost after the function returns(unless you return the new string of course)), using references is a little more convenient than using pointers, and a little safer too. Also, if the object is larger than a primitive, or the object cannot/should not be copied, you can pass as reference. If you don't want to modify the source object, just make the reference const.
So, as we're all hopefully aware, in Object-oriented programming when the occasion comes when you need somehow access an instance of a class in another class's method, you turn to passing that instance through arguments.
I'm curious, what's the difference in terms of good practice / less prone to breaking things when it comes to either passing an Object, or a Pointer to that object?
Get into the habit of passing objects by reference.
void DoStuff(const vector<int>& values)
If you need to modify the original object, omit the const qualifier.
void DoStuff(vector<int>& values)
If you want to be able to accept an empty/nothing answer, pass it by pointer.
void DoStuff(vector<int>* values)
If you want to do stuff to a local copy, pass it by value.
void DoStuff(vector<int> values)
Problems will only really pop up when you introduce tons of concurrency. By that time, you will know enough to know when to not use certain passing techniques.
Pass a pointer to the object if you want to be able to indicate nonexistence (by passing a NULL).
Try not to pass by value for objects, as that invokes a copy constructor to create a local version of the object within the scope of the call function. Instead, pass by reference. However, there are two modes here. In order to get the exact same effective behavior of passing by value (immutable "copy") without the overhead, pass by const reference. If you feel you will need to alter the passed object, pass by (non-const) reference.
I choose const reference as a default. Of course, non-const if you must mutate the object for the client. Deviation from using references is rarely required.
Pointers are not very C++ - like, since references are available. References are nice because they are forbidden to refer to nothing. Update: To clarify, proper containers for types and arrays are preferred, but for some internal implementations, you will need to pass a pointer.
Objects/values, are completely different in semantics. If I need a copy, I will typically just create it inside the function where needed:
void method(const std::string& str) {
std::string myCopy(str);
...
In fact what you can pass to a method is a pointer to object, a reference to the object and a copy of the object and all of these can also be constant. Depending on your needs you should choose the one that best suits your needs.
First descision you can make is whether the thing you pass should be able to change in your method or not. If you do not intend to change it then a const reference in probably the best alternative(by not changing I also mean you do not intend to call any non-const methods of that object). What are the advantages to that? You safe time for compying the object and also the method signature itself will say "I will not change that parameter".
If you have to change this object you can pass either a reference or a pointer to it. It is not very obligatory to choose just one of these options so you can go for either. The only difference I can think of is that pointer can be NULL(i.e. not pointing to any object at all) while a reference is always pointing to an existent object.
If what you need in your method is a copy of your object, then what you should pass a copy of the object(not a reference and not a pointer). For instance if your method looks like
void Foo(const A& a) {
A temp = a;
}
Then that is a clear indication that passing a copy is a better alternative.
Hope this makes things a bit clearer.
Actually, there's really no good reason for passing a pointer to an object, unless you want to somehow indicate that no object exists.
If you want to change the object, pass a reference to it. If you want to protect it from change within the function, pass it by value or at least const reference.
Some people pass by reference for the speed improvements (passing only an address of a large structure rather than the structure itself for example) but I don't agree with that. In most cases, I'd prefer my software to be safe than fast, a corollary of the saying: "you can't get any less optimised than wrong". :-)
Object-oriented programming is about polymorphism, Liskov Substitution Principle, old code calling new code, you name it. Pass a concrete (derived) object to a routine that works with more abstract (base) objects. If you are not doing that, you are not doing OOP.
This is only achievable when passing references or pointers. Passing by value is best reserved for, um, values.
It is useful to distinguish between values and objects. Values are always concrete, there's no polymorphism. They are often immutable. 5 is 5 and "abc" is "abc". You can pass them by value or by (const) reference.
Objects are always abstract to some degree. Given an object, one can almost always refine it to a more concrete object. A RectangularArea could be a Drawable which could be a Window which could be a ToplevelWindow which could be a ManagedWindow which could be... These must be passed by reference.
Pointers are a wholly separate can of worms. In my experience, naked pointers are best avoided. Use a smart pointer that cannot be NULL. If you need an optional argument, use an explicit optional class template such as boost::optional.
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?
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.
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.
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.
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.
To avoid making an unnecessary copy, thus improving performance.
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.
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).
An array can't be passed by value, so this is a good time to use a const pointer.