In Java, all variables containing proper objects are actually references (i.e. pointers). Therefore, method calls with these objects as arguments are always "by reference". Calling a method which modifies the state of the object also affects the original object (on the caller side).
C++ is different: Here arguments can be passed by value or passed by reference. Calling a mutator method on an object which was passed by value leaves the original object unaffected. (I suppose call by value creates a local copy of the object).
So my first response to this - coming from Java to C++ - is: ALWAYS use pointers when using objects as arguments. This gives me the behavior I have come to expect from Java.
However, one could also use "call by value" in case one does not need to modify the object in the method body. Are there reasons why one would want to do this?
No, in C++ always pass by reference, unless your function can be called with
nullptr
as a valid argument. If the function does not need to modify the argument, pass byconst
reference.Passing arguments by value has several uses.
If your function needs to create a copy of the argument it is better to create this copy by passing by value rather than creating a copy within the function. For instance:
Instead use
Doing this also has the benefit of allowing the compiler to move
widget
if possible, which is generally more efficient than creating copies.I think you should consider the variable types in your function signature as the contract to the caller. So if you declare you function as:
then you are saying i will copy your passed in value do whatever I like and it won't be modified.
If you declare like:
then I may modify what
a
points to or indeed modify the pointerso the semantic difference is that you are declaring what the contract of your function may do, with pointers and references (without const declared on the reference or the object that the pointer is pointing to) you may modify the variable.
References are preferred in C++ as it is clearer what you are intending and you avoid the c style pointer to pointer function signatures that are necessary when passing pointers to functions where you want to modify what the pointer is pointing to, which leads to errors and head scratching before you realise what went wrong.
Pointers though still are very useful as paremeters, especially if you need to test if the pointer to the object is null or not, something that is not possible to do using references.