This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
If I have a function that takes in some parameters and then does something with the parameters without needing to change their inherent value, is there any benefit from using pass by reference versus pass by value?
Yes. Passing by value copies the argument, which might be very expensive (or not even possible). If you want to pass by reference, but not modify the object, pass by const-reference.
As an example of an object that cannot be passed by value:
class Foo {
public:
Foo() {}
private:
Foo(const Foo&); // copy-constructor is not accessible
}
Here is the general guide:
Pass by reference when
You need to cause a side effect on the object that will be visible to the caller
or you cannot pass by value because of the lack of an accessible copy constructor or something and you need side effects
Pass by const reference when you have
A large object
and/or you cannot pass by value
and/or no need for side effects
Pass by value when
The object is small
and/or You do not need side effects
and/or You need a copy of the value to work with anyway
Related
In what circumstances should I prefer pass-by-reference? Pass-by-value?
There are four main cases where you should use pass-by-reference over pass-by-value:
If you are calling a function that needs to modify its arguments, use pass-by-reference or pass-by-pointer. Otherwise, you’ll get a copy of the argument.
If you're calling a function that needs to take a large object as a parameter, pass it by const reference to avoid making an unnecessary copy of that object and taking a large efficiency hit.
If you're writing a copy or move constructor which by definition must take a reference, use pass by reference.
If you're writing a function that wants to operate on a polymorphic class, use pass by reference or pass by pointer to avoid slicing.
There are several considerations, including:
Performance
Passing by value copies the data, so passing large data structures by value can inhibit performance. Passing by reference passes only a reference (basically the address) to the data. For large data structures, this can greatly improve performance. For smaller data structures (like an int), passing by reference can inhibit performance.
Modifications
Passing by value copies the data so if the target code modifies that copy, it will not affect the original. Passing by reference passes only the address of the data, so modifications made against that reference will be "visible" to the calling code.
Yes.
Pass by value for things like native types that are small enough that passing them directly is efficient. Otherwise use pass by (const) reference.
The hard part is writing a template that could apply to either (in which case, you usually want to use pass by reference -- the potential penalty for passing a large object by value is much worse than the potential penalty for passing by reference when passing by value would have been preferred).
Edit: this, of course, is assuming a situation where the required semantics would allow either one -- obviously if you're working with something like polymorphic objects, there's no real "preference" involved, because you must use a pointer or reference to get correct behavior.
As others already have replied to your question sufficiently well, I would like to add an important point:
If the class does not have public copy-constructor, then you don't have choice to pass by value; you have to pass by reference (or you can pass pointer).
The following program would not compile:
class A
{
public:
A(){}
private:
A(const A&) {}
};
//source of error : pass by value
void f(A ) {}
int main() {
A a;
f(a);
return 0;
}
Error:
prog.cpp: In function ‘int main()’:
prog.cpp:10: error: ‘A::A(const A&)’ is private
prog.cpp:18: error: within this context
prog.cpp:18: error: initializing argument 1 of ‘void f(A)’
See yourself at ideone : http://www.ideone.com/b2WLi
But once you make function f pass by reference, then it compiles fine : http://www.ideone.com/i6XXB
here's the simple rule:
pass by reference when the value is large.
the other answers are amazing. Just trying to make this simplest.
You have tagged your question with both C and C++.
Therefore, I suggest that you consider using pass by reference in C++ which supports this feature and that you do not consider using it in C which does not support this feature.
pass by reference can be called only in below conditions:
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.
Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments.
The difference between pass-by-reference and pass-by-pointer is
that pointers can be NULL or reassigned whereas references cannot.
Use pass-by-pointer if NULL is a valid parameter value or if you want to reassign the pointer.
Otherwise, use constant or non-constant references to pass arguments.
While pointers are references, "reference" in c++ usually refers to the practice of tagging a parameter of SomeType&.
Which you should never do. The only place it is appropriate is as a magic syntax required to implement the various pre-defined operators. Otherwise:
You should never pass out parameters by reference - pass by pointer, otherwise you make code reviews all but impossible. Pass by reference makes it impossible to tell by examining a call which parameters can be expected to be changed.
You should never pass in parameter by reference either. Again, this means you are performing a meta optimization. You should always just pass-by-value, otherwise you are guilty of peeking inside an object, examining its implementation and deciding that pass-by-reference is preferred for some reason.
Any c++ class should implement all the copy and assignment constructors and overloads necessary to be passed around by value. Otherwise it has not done its job, of abstracting the programmer from the implementation details of the class.
This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 6 years ago.
I'm wondering if there is any difference between passing an object reference as a parameter or as an argument. Is the code below equivalent? Is there situations where I should use one or the other?
void foo(Object &object){
object.update()
}
Object object
foo(object)
VS
void bar(Object *object){
object->update()
}
Object object
bar(&object)
You seem a bit confused. None of your examples pass by value. First example passes by reference, the second passes by pointer.
The main differences are:
Pass by value foo(Object object): the function gets a copy of the argument and cannot change the original.
Pass by reference foo(Object& object): the function gets a reference (not copy) to the original object and can modify it. References cannot be "un-bound", they always refer to a valid object (with certain exceptions which are usually bugs).
Pass by pointer foo(Object* object): as passing by reference, except it is valid for the pointer to not refer to anything (it can be nullptr which is useful if you need to signal that).
When you take by reference and the function can be inlined, the compiler is - theoretically - not required to generate the address of the instance. Depending on your type, unary prefix operator&() might do more than just returning this. Also, it's valid for a pointer to be nullptr, you should check for that (or use gsl's not_null).
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pass by Reference / Value in C++
I was wondering what the difference is between a call by value/reference/name. And why would it be beneficial to use one over another?
call by value: a copy of the parameters is passed to the function
call be reference: no extra copy is made, the caller's variable is passed directly.
Major difference is that one extra unnecessary copy is made in call by value paradigm... You should always use call be reference (or const reference) unless a callee needs to modify the variable and you don't want the changes to your caller's variable...
Call by value creates a copy of the argument which gets passed to the function - so for a large object that could create a large overhead. It also stops you making any changes to the argument inside the function as they will be reflected in the copy only. Call by reference passes a reference to the object and so changes can be made to that object - unless of course you pass by const reference.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it better in C++ to pass by value or pass by constant reference?
I'm aware of the differences of passing by value, pointer and reference in C++, and I'd consider passing objects by value (instead of const reference) in C++ to be almost always a programming error.
void foo(Obj o); ... // Bad
void foo(const Obj &o); ... // Better
The only case I can think of where it might be appropriate to pass by value instead of const reference is where the object is smaller than a reference, and passing by value is therefore more efficient.
But, surely this is the sort of thing that compilers are built to determine?
Why does C++ actually need pass by value AND pass by const reference, and - are compilers allowed to automatically convert the call to (and from) a const reference if appropriate?
(There seem to be 100s of C++ calling convention question, asking about the differences between (say) value and reference - but I couldn't find one that asked "why?".)
The question of when passing by value might be better than by const reference has different answers with different versions of the standard.
In the good old C++03, and a few years ago, the recommendation would be to pass anything that does not fit in a register by const reference. In this case, the answer would be:
Because Obj fits in a register and passing by value and passing by value will be more efficient
Still in C++03, in the last years (absurd as it seems some articles recommended this almost 10 years back, but there was no real consensus),
if the function needs to make a copy, then doing so in the interface allows the compiler to perform copy-elision if the source for the copy is a temporary, so it can be more efficient.
With the approval of the new C++11 standard, and increasing compiler support for rvalue-references, in many cases even when the copy cannot be elided, and again
if the function needs to make a copy, even when the copy cannot be elided, and for types that support it, the contents will be moved (in common jargon the object will be moved, but it is only the contents that get shifted), which again will be more efficient than copying internally.
As of the question of why the two different calling conventions, they have different goals. Passing by value allows the function to modify the state of the argument without interfering with the source object. Additionally, the state of the source object will not interfere with the function either (consider a multithreaded environment, and a thread modifying the source while the function is still executing).
Certainly one reason C++ has pass-by-value is because it inherited it from C, and removing that could break code for little gain.
Secondly as you note, for types that are smaller than a reference passing by value would be less efficient.
Another less obvious case however is if you have a function that needs a copy of its argument for some reason:
void foo(const Obj& obj)
{
if(very_rare_check()) return;
Obj obj_copy(obj);
obj_copy.do_work();
}
In this case note that you're forcing a copy. But suppose you call this function with the result of another function that returns by value:
Obj bar() { return Obj(parameters); }
And call it thusly: foo(bar());
Now when you use the const reference version, the compiler will end up making two objects: The temporary, and the copy in foo. If however you passed by value the compiler can optimize away all the temporaries to the location used by the by-value parameter of foo.
There's a great article about this and move semantics in general at http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
Finally the canonical way to implement certain operators is to use pass-by-value to avoid copies inside the operator:
Obj operator+(Obj left, const Obj& right)
{
return left += right;
}
Note how this lets the compiler generate the copy in the parameter rather than forcing a copy or temporary object within the operator's code itself.
If I wanted to do things to the object within the function without affecting the original, I would pass by value:
A minus(A b){
b.val=-b.val;
return b;
}
The copy swap idiom uses passe by value to achieve a compiler generated copy.
MyClass& operator=(MyClass value) // pass by value to generate copy
{
value.swap(*this); // Now do the swap part.
return *this;
}
Basically in situations where you will need to modify the parameter but do not want to touch the original. In these situations if you pass by const reference you manually need to create a copy inside the function. This manual steps will prevent certain optimizations that the compiler can perform if you let the compiler handle the copy.
MyClass a;
// Some code
a = MyClass(); // reset the value of a
// compiler can easily elide this copy.
If the object is mutable, passing by value gives the receiver its own copy to use and where sensible change, without affecting the caller's copy - always assuming it's a sufficiently deep copy.
This may simplify thinking in some multi-threaded situations.
Why does C++ actually need pass by value AND pass by const reference, and - are compilers allowed to automatically convert the call to (and from) a const reference if appropriate?
Let me answer the second one first: sometimes.
Compilers are allowed to elide the copy into the parameter, but only if you pass in an rvalue temporary. For example:
void foo(Obj o);
foo((Obj()))); //Extra set of parenthesis are needed to prevent Most Vexing Parse
The copying of the temporary into the argument parameter may be elided (ie: not copied), at the compiler's convenience).
However, this copy will never be elided:
Obj a;
foo(a);
Now, on to the first. C++ needs both because you may want to use both for different things. Pass by value is useful for transferring ownership; this is more important in C++11 where we can move rather than copy objects.