Reputation: 1058
I was wondering if:
//Let's say T is a big class with + operand implemented.
T add(T* one, T* two)
{
return *one + *two;
}
and:
T add(T& one, T& two)
{
return one + two;
}
is lighter than this:
T add (T one, T two)
{
return one +two;
}
If not, then why would someone use pointers or references to an object instead of the objects themselves as function's arguments if nothing will change the object's data?
Upvotes: 1
Views: 143
Reputation: 61009
For light types, i.e. ones that fit into a register such as int
, it doesn't make a difference as they are just as easy to copy as a pointer to them. Actually the additional indirection might harm the performance instead, which is why you should avoid introducing it if not needed.
However, the types used could be expensive to copy. An every day example is std::string
. References avoids copies and are favoured wherever a function requires "heavy" objects.
In function templates one should generally use references when taking various object types, unless you are certain that the only types involved are "light", such as iterators or scalars.
There are less obvious exceptions to this rule though. Consider std::accumulate
:
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
Here, init
is taken by value. The reason is rather simple: In usual implementations init
is modified as it is directly used inside the computations - no intermediate object is introduced.
template<class InputIt, class T>
T accumulate(InputIt first, InputIt last, T init)
{
for (; first != last; ++first) {
init = init + *first; // Here
}
return init;
}
Pointers should per se not be used for indirect function parameters. They are used in C, where references don't exist.
Upvotes: 4
Reputation: 67345
No, your last version is "lighter".
But that's because int
arguments can easily be passed on the stack. For larger data types, classes, etc., passing pointers is more efficient.
Also, if you needed to change the value of one of the arguments inside your function, you would need a pointer (of which references are a type of) to it in order to modify it.
Upvotes: 1
Reputation: 73304
If by "lighter" you mean "more efficient", the answer (for ints) is no -- the only time passing argument by pointer or by reference might be more efficient that passing by value is if the object you are passing is very large (e.g. sizeof(theObjectType) is significantly larger than the 4 or 8 bytes which is the typical size of a pointer), or if the object's class has a copy constructor whose implementation is computationally expensive. Note that when passing by pointer or by reference, the CPU has to dereference the pointer/reference when accessing the data, which isn't entirely cost-free.
If not, then why would someone use pointers or references to an object instead of the objects themselves as function's arguments if nothing will change the object's data?
It could be that they want to communicate to the function a specific instance of the object rather than (only) the contents of the object. For example, it's possible (although bad practice) to write a function that behaves differently if you passed in a pointer-to-a-particular-global-object than it would behave if passed in any other pointer.
Passing by pointer also gives the caller the option of passing in NULL as an argument, which can be useful if you want the caller to be able to specify "no value has been provided for this argument".
Upvotes: 3
Reputation: 45704
The answer, as so often, is: It depends.
If you want to know whether copying or passing by reference is cheaper, or the right thing, consider these:
How expensive is copying the object, compared to a pointer to it.
Anyway, depending on how the argument gets passed, sometimes the copy can be omitted.
For an int
, the pointer/reference is at best no more expensive.
Remember that you can always pillage arguments passed by value ruthlessly, just like those passed by rvalue-reference.
Not so for others.
Not that those considerations are of consequence for int
, or other types not managing more expensive resources.
std::optional
.Anyway, never pass by non-const
pointer or reference, unless it should be modified by the function.
Also, if you are serious about performance, always measure.
And remember that most of the time is spent in only a small part of your code.
Upvotes: 1
Reputation: 652
When using primitive type, pass by pointer or reference it is not lighter than pass by value. But if it is a large object, pass by pointer or reference will be lighter than pass by value, because of the overhead in copying large object.
Upvotes: 4