5

In what situations it is preferred to return an object instead of just modifying an object passed to that function by reference? How do I know which one should I pick?

Actually, the question is if there are things I wouldn't be able to do without the ability to return an object from function, but instead only modifying objects passed by reference.

dan1st
  • 12,568
  • 8
  • 34
  • 67
user107986
  • 1,461
  • 1
  • 17
  • 24
  • You can return an immutable object, but can't (by definition) modify one passed in by reference. – Igor Tandetnik Oct 04 '14 at 14:06
  • 1
    Relevant: http://stackoverflow.com/questions/321068/returning-multiple-values-from-a-c-function – πάντα ῥεῖ Oct 04 '14 at 14:06
  • 2
    Returning the "result" of a function by value is considered "cleaner" as it fits the mathematical view of a function, and can result in more convenient code. However, if the object is expensive to create, reusing objects by passing them by reference for the result to be stored, can result in a performance increase. – Neil Kirk Oct 04 '14 at 14:07
  • 1
    If the returned values/objects are not heavy, return them by value(Eg. int, long, bool etc.). If they are heavy objects (Eg. a vector) modify the value passed by reference. But remember C++11 has rvalue references which may make even returning heavy objects(such as a vector) not that heavy. – Nipun Talukdar Oct 04 '14 at 14:13

4 Answers4

5

The main pragmatic difference between

 TYPE function () ;

and

 void function (TYPE &value) ;

is that the former can be used in expressions.

a = 10 * function () ;

if (function ()) { }

That is the main design consideration.

Beyond that, I would have to get into opinion. I am going to stick to the objective difference.

user3344003
  • 20,574
  • 3
  • 26
  • 62
  • That is what I just have been thinking about. A very good example are operators. Those usually transform things and return the result. Without them it would not be possible to write vector algebra in the traditional readable form. – Tobias Oct 04 '14 at 14:26
3

Its very simple...

Return by "value": - If you want a copy of the object with the current state of the object; - And inst important if the state of the original object change latter;

Return by reference: - If you want to have the correct state when the object is updated by others; - If you want to change the state of the object, and others be aware of that changes;

Those are the most important reasons.

But exist a special use case that you must be aware:

By techinical reasons, the current languages normally are faster when you return by reference. If speed is a requirement you should also consider this constraint to take the best decision.

But the fundamental decision is about how you want to deal with the state of the object.

1

Returning something is the easy option but you'll use the reference if something speaks against it. One reason is because you have something else in mind for the return value, like a success/failure code. Another is because it would look big on the stack and you're on a tiny computer. Then, of course, you might want to modify an existing variable or structure instead of making a new one. I think that's it.

I'm not aware of anything you can't do by passing a reference or pointer to receive the result.

Adrian May
  • 2,127
  • 15
  • 24
  • One more reason: if it would be a horrible error to ignore the return value, in C++ you may be better off taking a parameter by reference and "returning" your result that way. This is because unfortunately GCC's `warn_unused_result` attribute doesn't work in C++, and for certain functions ignoring the return value is an awful error. For example `system()` is sort of like that, but other functions in user libraries may be even worse (I've seen some, e.g. where the result is an RAII type whose deletion would "undo" the function call, sort of like a Python context manager). – John Zwinck Oct 04 '14 at 14:15
0

No one has mentioned speed, so I'll just add this tid-bit:

Passing by reference or pointer is frequently faster than passing by value (so long as the size of a pointer is < the size of the value)

Returning/passing by reference is faster (same as returning by a pointer) than returning by value if sizeof(object) > sizeof(void *), or in other words, if the size of the object being returned is larger than the size of any pointer on the system (all pointers on a given system have the same size), which is 8 bytes on most systems.

So, if you're returning any integer, float, or double type, returning by value is as fast or faster than returning by pointer. If you're returning a 9 byte, 10 byte, or 1200 byte object, however, returning by reference or pointer is faster, and much much faster for the 1200-byte-object case.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265