views:

189

answers:

8

I am confused between :

  • returning an object (but then the object is copied from the local variable in the function, which consumes memory)
  • returning a pointer (but then you have to remember to delete it, in the calling code, which is weird)
  • returning a reference (but this is not possible because this would be a reference to a local variable of the function, which would be deleted as soon as the function ends)

I am looking for the proper way to return an object from a C++ function, in basic C++ (no library handling pointers and freeing memory automatically). I want to know how this is supposed to be done.

Thank you

+3  A: 

What about std::auto_ptr from <memory>? Or if C++0x is concerned std::unique_ptr?

Armen Tsirunyan
I think he's asking about more fundamental patterns.
quixoto
@quixoto: Well do provide them :)
Armen Tsirunyan
@Armen: I don't have a great answer here, was watching the question myself.
quixoto
+5  A: 

Modern compilers typically implement the (Named) Return Value Optimization, by which the copy you reference (and would logically expect) is not done.

Ever since Visual Studio 2005 (VC++ 8.0) I don't think twice about returning objects.

Steve Townsend
oh ! gcc too ? It seems like a "trick"... C++ just seems wrong :(
Matthieu
+1: Trust your compiler, RVO/NRVO are very effective at their job.
DeadMG
gcc and intel too, yes. Every compiler worth its salt does this.
Blindy
OK this seems like "the" answer. But it's so weird so many people don't seem to know that (look at the other answers)... it keeps the confusion alive. Thank you anyway !
Matthieu
@Matthieu - I did not know about this myself until I was trying to work out why Visual C++ 7.1 code was spending so much time in object copying. Just moving to Visual C++ 8.0 made it measurably faster, and I wanted to find out why.
Steve Townsend
@Matthieu (like your name ;)) In fact, gcc is more aggressive that VC++ in this regard, since it performs this optimization even in at -O0. It's just that common.
Matthieu M.
A: 

Return by value unless you need subtype polymorphism. In the latter case, I would return an auto_ptr<T> (C++03) or a unique_ptr<T> (C++0x).

FredOverflow
+1  A: 

Depends on the "semantics" of the object. Values should be returned by copy while entities should (or must, since they are ideally not copyable) be returned by pointer or reference.

References should be used when possible. But if you must return a pointer, using a smart pointer class such as std::auto_ptr or boost::shared_ptr is a good idea, because then the calling code don't have to wonder about freeing it when it is done with it.

Etienne de Martel
A: 
  • Return one of the smart pointer choices (either having to depends on extra libraries or wait until C++1x)
  • Use pass by reference

Personally I prefer the second option because it is clear that the user needs to allocate and delete memory.

Dat Chu
Is C++0x done? I know some compilers support parts of it now, but it isn't finalised is it?
PhilCK
@PhilCK: No we all HOPE it will be finalized next year. Though some believe that 2012 is more realistic.
Armen Tsirunyan
Hence the 1x. Some says that it will eventually be 2x -_- I certainly hope not.
Dat Chu
@PhilCK: The final committee draft was approved in March. It is fully expected that only small bugfixes and edits will occur from now on. It's likely to pass as ISO C++11 next year, and will not be substantially different than the FCD that's already out.
Ken Simon
+2  A: 

Assuming "no library handling pointers and freeing memory automatically" means no return-by-pointer, no boost::shared_ptr and no std::unique_ptr (std::auto_ptr is evil anyway), you have two choices:

Return by value:

Foo bar(quux)
{
    Foo foo;
    foo.frobnicate(quux);
    return foo;
}

Foo foo = bar("fred");

Pass by reference:

void bar(Foo& foo, quux)
{
    foo.frobnicate(quux);
}

Foo foo;
bar(foo, "fred");
Frédéric Hamidi
+1 for the "explicit object in caller, reference outparam" pattern.
Zack
+3  A: 

A few rules of thumb regarding returning objects from functions:

Return per copy, except when

  1. you return a non-local object (like a class member, static variable etc.) of a type that you would pass to a function per const reference; you can return this per const reference
  2. you return a non-local object and callers should be able to invoke modifying members of the returned object, thereby manipulating an object stored elsewhere; return this per non-const reference
  3. you return a derived class in a polymorphic class hierarchy, users of the object should only know the base class, and neither #1 nor #2 apply; return this per smart pointer
sbi
A: 

returning an object (but then the object is copied from the local variable in the function, which consumes memory)

Optimal compilers may not take significant time to create copy. You may also need to implement copy constructor and overload assignment operator, depending upon your object contents.

returning a pointer (but then you have to remember to delete it, in the calling code, which is weird)

Yes, you have to remember to delete it as you do not want to consider automatic cleanup for this question.

returning a reference (but this is not possible because this would be a reference to a local variable of the function, which would be deleted as soon as the function ends)

Returning reference is useful when you are returning this object(*this) from member functions. Otherwise, like you mentioned its not possible to use.

Overall: it depends upon your need as described above regarding which one to choose when.

bjskishore123