This is a follow-up to this question. Suppose I have this code:
class Class {
public virtual method()
{
this->~Class();
new( this ) Class();
}
};
Class* object = new Class();
object->method();
delete object;
which is a simplified version of what this answer suggests.
Now once a destructor is invoked from within method()
the object lifetime ends and the pointer variable object
in the calling code becomes invalid. Then the new object gets created at the same location.
Does this make the pointer to the object in the calling valid again?
Creating a new object at the location of a destroyed one does not make any pointers valid again. They may point to a valid new object, but not the object you were originally referencing.
You should guarantee that all references were removed or somehow marked as invalid before destroying the original object.
This would be a particularly difficult situation to debug.
The
object
pointer doesn't become invalid at any time (assuming your destructor doesn't calldelete this
). Your object was never deallocated, it has only called it's destructor, i.e. it has cleaned up its internal state (with regard to implementation, please note that standard strictly defines that the object is destroyed after destructor call). As you have used placement new to instantiate the new object at the exactly same address, it is technically ok.This exact scenario is covered by section 3.8.7 of C++ standard:
That said, this is interesting only as learning code, as production code, this is horrible :)
Strictly, this is fine. However, without extreme care, it will become a hideous piece of UB. For example, any derived classes calling this method won't get the right type re-constructed- or what happens if
Class()
throws an exception. Furthermore, this doesn't really accomplish anything.It's not strictly UB, but is a giant pile of crap and fail and should be burned on sight.
You may want to reconsider explicitly calling the destructor. If there's code you want executed that happens to be in the destructor, move that code to a new method and call that method from the destructor to preserve the current functionality. The destructor is really meant to be used for objects going out of scope.
The pointer only knows its address and as soon as you can confirm that the address of the new object is the one the pointer is pointing to, the answer is yes.
There are some cases where people would believe the address does not change, but in some cases it does change, e.g. when using C's
realloc()
. But that's another story.This is explicitly approved in 3.8:7:
The example given is: