I want to explicitly destroy an object (call the destructor on it and all its fields), but it may happen that I still hold some pointers to the object in question. Thus, I don’t want to yet free the memory; instead I would like to leave a sort of a flag “I am a destroyed object”.
I came with an idea of the following approach:
class BaseClass { //all objects in question derive from this class
public:
BaseClass() : destroyed(false) {}
virtual ~BaseClass() {}
private:
bool destroyed;
public:
bool isDestroyed() { return destroyed; }
void destroy() {
this->~BaseClass(); //this will call the virtual destructor of a derivative class
new(this) BaseClass();
destroyed=true;
}
};
When destroy is called, I basically destroy the whatever object I had (perhaps a derivative one) and create a new “zombie” one in that very same place. As a result I hope to achieve:
- Any other pointer
ptrpreviously pointing to this object can still callptr->isDestroyed()to verify its existence. - I am aware that if I don’t check the flag of the zombie and try to access fields belonging to any derived object, bad things may happen
- I am aware that the zombie object still consumes as much memory as the destroyed object (as it may be a derivative of
BaseClass) - I still have to free memory of the destroyed object. I hope however, that calling
deleteis still correct?
Questions:
Are there any other problems which I should consider when using the above pattern?
Will calling delete on the zombie object correctly free whole memory consumed by the previous (normal) object?
While I appreciate your input on how to do it differently, and I may be inclined to do it your way – I would still like to understand all the risks that the above code poses.
You got some nasty comments to your question. Now I don’t think they are deserved although there may be better ways to do what you want. I understand where you are coming from but actually you are using the destructor the same way you would use the reset function you refuse to write. Actually you gain nothing from calling a destructor since calling a distructor has nothing to do with actually deleting or resetting anything unless you actually write the code to do it within the destructor.
As to your question about the placement new:
As you may know already the placement new doesn’t allocate any memory so calling it will just create the object in the same place. I understand that is exactly what you want but it’s just not ncessary. Since you don’t call delete on your object just destroy, you can set destroyed to true without initializing the class.
To sum it up:
To do what you want to do correctly and gain the benefits of destructors, you should overload the new and delete operators of your classes and use the normal destruction mechanism. You can then opt not to release the memory but mark it as invalid or maybe release most of the memory but leave the pointer pointing to some flags.
EDIT
Following the comments I decided to sum up all the risks I see and the risks that others have pointed out:
And I repeat my suggestion – overload delete and new for what you want