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.
someFunc(obj)
it would be best to use obj.someFunc()
) but there are plenty of times where 1 is still preferred such as void someFunc(Obj obj) { this.registerSomeFunc(); obj.someFunc(); }
Regardless, 2 is all but required for all but the most trivial objects. –
Cardamom pointers
every now and then, but frankly I am not impressed. You exchange a "notification" of the caller for a possible nullptr
issue. I prefer securing against the latter and give the function a sufficiently descriptive name so that it expresses the possible modification... if any. –
Uncovered 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.
int
inhibit performance? –
Army here's the simple rule:
pass by reference when the value is large.
the other answers are amazing. Just trying to make this simplest.
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
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.
© 2022 - 2024 — McMap. All rights reserved.