But there is no f any more in that case.
Well, the pointer f
goes out of scope, that's true, but we are still returning a pointer to the same object that f
pointed to.
Therefore, we still have a handle to that object and we still can invoke delete
on the returned pointer. In fact, you can invoke delete
any time after creating an object with new
.
What you have to take care is that:
- you do indeed invoke
delete
at some point for each object allocated with new
(otherwise you have a memory leak);
- you do not call
delete
more than once for the same object, otherwise you get undefined behavior;
- you do not dereference a pointer which points to an object that has been destroyed (i.e. a "dangling pointer"), otherwise you get undefined behavior.
In general, manual memory management through new
and delete
is discouraged in Modern C++, and ownership policies should be realized through smart pointers instead. OR...
In the four method below, only better is what we should do
Not exactly. In fact, I would say we should definitely not do better()
- although we could do a version of better()
modified to create and return a smart pointer rather than an owning raw pointer.
However, function mediocre()
is actually pretty good, and that is for two reasons:
- First of all because it is very likely that the compiler will elide the call to the copy constructor and perform (Named) Return Value optimization, thus resulting in no run-time overhead;
- Secondly, because thanks to C++11's move semantics, it is possible to
equip
Foo
with a move constructor that makes returning by value
efficient in most cases even when no elision is performed.
Moreover, as Zoidberg correctly mentions in the comments, you should not use pointers at all if you do not really need them. Unique ownership can often by realized by creating objects with automatic storage duration (aka "on the stack"), and move semantics makes this practice efficient. Pointers should be created only when you need reference semantics.