4

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

Matthieu Napoli
  • 42,736
  • 37
  • 154
  • 239

8 Answers8

8

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
  • 51,210
  • 8
  • 87
  • 134
  • 1
    oh ! gcc too ? It seems like a "trick"... C++ just seems wrong :( – Matthieu Napoli Oct 17 '10 at 14:53
  • 1
    +1: Trust your compiler, RVO/NRVO are very effective at their job. – Puppy Oct 17 '10 at 14:55
  • gcc and intel too, yes. Every compiler worth its salt does this. – Blindy Oct 17 '10 at 17:32
  • 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 Napoli Oct 17 '10 at 20:40
  • @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 Oct 17 '10 at 20:49
  • @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. Oct 18 '10 at 07:19
3

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

Armen Tsirunyan
  • 120,726
  • 52
  • 304
  • 418
3

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
Community
  • 1
  • 1
sbi
  • 204,536
  • 44
  • 236
  • 426
2

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");
Community
  • 1
  • 1
Frédéric Hamidi
  • 240,249
  • 39
  • 455
  • 462
1

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
  • 30,360
  • 7
  • 86
  • 102
0

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
  • 237,063
  • 85
  • 359
  • 638
0
  • 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
  • 9,802
  • 12
  • 51
  • 78
  • Is C++0x done? I know some compilers support parts of it now, but it isn't finalised is it? –  Oct 17 '10 at 14:57
  • @PhilCK: No we all HOPE it will be finalized next year. Though some believe that 2012 is more realistic. – Armen Tsirunyan Oct 17 '10 at 15:10
  • Hence the 1x. Some says that it will eventually be 2x -_- I certainly hope not. – Dat Chu Oct 18 '10 at 00:30
  • @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 Oct 22 '10 at 18:06
0

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
  • 5,847
  • 9
  • 37
  • 65