When you want to return an instance from a method, do you create the object and send a pointer back, or a reference back? Whats the correct method and the method signature for this?
There are a lot of ways to do this in C++. Unfortunately most of them result in confusion on who is responsible for allocating and deallocating the object. There are two methods that I recommend:
// Return a real object, automatic stack allocation.
Foo GetFoo1()
{
Foo f;
// Init f.
return f;
}
// Use a smart, reference counted pointer that handles deallocation itself.
boost::shared_ptr<Foo> GetFoo2()
{
boost::shared_ptr<Foo> f(new Foo);
// Init f
return f;
}
If I'm creating an instance purely to return, I would return by value as first preference.
Only if the object type was not practically copyable would I consider returning via a smart pointer encapsulating the transfer of ownership.
Returning a reference I reserve for returning a reference to an object whose ownership isn't being transferred out of the function, that is it is already owned by something else and it's existence is guaranteed until a defined time after the function returns.
If you're referring to something like a Factory Method, typically you return a pointer. Better still, return a smart pointer and you don't create more leaks by virtue of using a raw pointer.
Example:
std::auto_ptr<Gizmo> MyFactory::CreateGizmo()
{
return new Gizmo;
}
Either return by value (people incorrectly assume that this is slow) or, if you're returning an override of a polymorphic type, return an auto_ptr (or better a unique_ptr in C++0x).
The reason you do NOT use a shared_ptr is that you can never get your pointer out of it and use a different ownership semantic.
Never return a reference to a local instance.
This really depends on the scope of your instance which controls the lifetime of the instance. If this is a local instance, you may return by value but will incur the cost of constructing & destructing the object twice (unless you use RVO). The other option is to return a pointer by constructing the object in the heap inside your function. However, with this approach the client will be responsible for deleting the allocated memory & is always prone to memory leaks. This is why you will need to use some kind of a smart pointer. Anders Abel code clearly illustrates the above two approaches with code examples. BTW, you cannot return a reference to a local instance since the instance will go out of scope once the function ends.
The answer depends on what exactly you are doing and who is responsible for deallocating.
First method: allocate on the heap and return. Who ever called the function will be responsible for deleting the returned pointer.
SomeObject* constructObject ()
{
SomeObject* obj = new SomeObject ();
return obj;
}
Then in some other function
void functionThatNeedsObject ()
{
SomeObject* obj = constructObject ();
//You must delete obj when done
}
Second method: Return a reference. You must be careful not to go out of scope by returning local or temporary variables.
Dont do this:
int& DoubleValue(int nX)
{
int nValue = nX * 2;
return nValue; // return a reference to nValue here
} // nValue goes out of scope here
You can return references to member variables or variables passed as arguments to the function.
SomeStruct& RefFunction(SomeStruct& nX, SomeStruct& nY)
{
return nX;
} //nX is still in scope because it was passed to us