Je veux détruire explicitement un objet (appeler le destructeur sur lui et tous ses champs), mais il se peut que je détienne encore des pointeurs vers l'objet en question. Ainsi, je ne veux pas encore libérer la mémoire ; à la place, je voudrais laisser une sorte de drapeau "je suis un objet détruit".
J'ai eu l'idée de l'approche suivante :
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;
}
};
Lorsque destroy
est appelé, je détruis l'objet que j'avais (peut-être un objet dérivé) et je crée un nouvel objet "zombie" au même endroit. Le résultat que j'espère obtenir :
- Tout autre pointeur
ptr
qui pointaient auparavant sur cet objet peuvent encore appelerptr->isDestroyed()
pour vérifier son existence. - Je suis conscient que si je ne vérifie pas le drapeau du zombie et que j'essaie d'accéder aux champs appartenant à un objet dérivé, de mauvaises choses peuvent se produire
- Je suis conscient que l'objet zombie consomme toujours autant de mémoire que l'objet détruit (car il peut être un dérivé de
BaseClass
) - Je dois encore libérer la mémoire de l'objet détruit. J'espère cependant que l'appel
delete
est toujours correcte ?
Questions :
Y a-t-il d'autres problèmes dont je dois tenir compte lorsque j'utilise le modèle ci-dessus ?
Appel de la volonté delete
sur l'objet zombie libère correctement toute la mémoire consommée par l'objet précédent (normal) ?
Bien que j'apprécie votre contribution sur la façon de procéder différemment, et que je sois peut-être enclin à le faire à votre façon, je voudrais quand même comprendre tous les risques que le code ci-dessus pose.