First off, when returning an unnamed object such as:
Object* func() { return new Object(); }
is that an anonymous variable, temporary variable, neither, or both? Does having it unnamed cause it to be temporary- as in it goes out of scope once func returns? Could I extend its scope by assigning it to a pointer or reference in the calling code block or would that be illegal/dangerous?
My second worry is that since it is created with new
if I were to:
Object *var = func()
somewhere else, would I need to delete
it afterwards? If I did not delete it I'm assuming that would cause a memory leak.
If instead I returned a reference:
Object& func() { return new Object(); }
and I assigned the new object to a pointer or reference, would accessing the object be illegal/dangerous?
Also, if I am missing any other terminology here, please say something about it.
Object* func() { return new Object(); }
This allocates an object with new
(that must be freed with delete
or there will be a leak) and returns a pointer to it by value.
Object& func() { return new Object(); }
This is illegal. It claims it returns a reference to an Object
, but new Object
returns a pointer to an object. If we fix that:
Object* & func() { return new Object(); }
We still have a problem -- this allocates an object with new
and returns a reference to a temporary pointer to it. This is illegal -- you can't return a reference to a temporary. It's no different from:
Object* & func() { Object* j = new Object(); return j; }
It should be clear that this is invalid. You're returning a reference to j
, but j
no longer exists after you return.
Though it's not idiomatic, you could do this:
Object& func() { return *(new Object()); }
This allocates a new Object
, and returns a reference to it. The Object
is not a temporary, so this is safe. The caller would still have to delete
it to avoid leaks.
The object you allocated and the pointer to it that's returned by new
are two different (but related) things.
The idiomatic way to do this is just to return the object by value. If you must dynamically allocate it, you should use some kind of smart pointer to avoid manually managing the lifetime.