How to "return an object" in C++?

Solution 1:

I don't want to return a copied value because it's inefficient

Prove it.

Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.

Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.


That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.

If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!

Solution 2:

Just create the object and return it

Thing calculateThing() {
    Thing thing;
    // do calculations and modify thing
     return thing;
}

I think you'll do yourself a favor if you forget about optimization and just write readable code (you'll need to run a profiler later - but don't pre-optimize).

Solution 3:

Just return a object like this:

Thing calculateThing() 
{
   Thing thing();
   // do calculations and modify thing
   return thing;
}

This will invoke the copy constructor on Things, so you might want to do your own implementation of that. Like this:

Thing(const Thing& aThing) {}

This might perform a little slower, but it might not be an issue at all.

Update

The compiler will probably optimize the call to the copy constructor, so there will be no extra overhead. (Like dreamlax pointed out in the comment).

Solution 4:

Did you try to use smart pointers (if Thing is really big and heavy object), like shared_ptr:



    std::shared_ptr calculateThing()
    {
        std::shared_ptr<Thing> thing(new Thing);
        // .. some calculations
        return thing;
    }
    
    // ...
    {
        std::shared_ptr<Thing> thing = calculateThing();
        // working with thing
    
        // shared_ptr frees thing 
    }