Question

    

Cette question a déjà une réponse ici:

    
            
  •              Est supprimer ce permis?                                      10 réponses                          
  •     
    

Dans mes tests de base initiale, il est parfaitement sûr de le faire. Cependant, il m'a frappé que tenter de manipuler this plus tard dans une fonction qui deletes this pourrait être une erreur d'exécution. Est-ce vrai, et est normalement sans danger delete this? ou ne sont là que certains cas dans lesquels il est sûr?

Était-ce utile?

La solution

delete this est légal et fait ce que vous attendez: il appelle le destructeur de votre classe et sans la mémoire sous-jacente. Après les retours de delete this, la valeur de votre pointeur ne this pas changement, il est maintenant un pointeur ballants qui devrait pas déréférencement. Cela inclut le déréférencement implicite en utilisant les variables membres de la classe.

Il se trouve généralement dans les classes compté référence qui, lorsque l'arbitre-compte est décrémenté à 0, le DecrementRefCount() / Release() / whatever fonction membre appelle delete this.

delete this est généralement considéré comme une forme très mauvaise pour de nombreuses raisons. Il est facile d'accéder accidentellement variables membres après delete this. Code de l'appelant pourrait ne pas réaliser votre objet a autodétruit.

En outre, delete this est une « odeur de code » que votre code ne pourrait pas avoir une stratégie symétrique pour la propriété de l'objet (qui attribue et qui supprime). Un objet ne aurait pu s'alloué avec new, afin d'appeler delete this signifie que la classe A alloue un objet, mais la classe B est de libérer plus tard [auto].

Autres conseils

Il est sûr de supprimer « cette » tant qu'il est essentiellement la dernière opération dans la méthode. En fait, plusieurs API de niveau professionnel le font (voir la mise en œuvre de CComObject ATL pour un exemple).

Le seul danger tente d'accéder à d'autres données membres après avoir appelé « supprimer ce ». Cela est certainement dangereux.

Supprimer c'est parfaitement légal que d'autres ont déjà mentionné. Il est risqué pour une raison supplémentaire qui n'a pas été encore mentionné - vous présumez que l'objet a été alloué sur le tas. Cela peut être difficile à garantir, bien que dans le cas des mises en œuvre de comptage de référence est généralement pas un problème.

mais ne le faites pas dans le destructor!

Comme indiqué par d'autres, supprimer c'est un idiome valide, mais pour qu'il soit en sécurité, vous devez vous assurer que l'objet est instancié jamais sur la pile.

Une façon de le faire est de rendre à la fois le constructeur et la création d'objet privé et de faire respecter destructor par une fonction d'usine de classe qui crée l'objet sur le tas et renvoie un pointeur vers elle. L'usine de classe peut être une fonction membre statique ou une fonction ami. Le nettoyage peut être fait par une méthode Delete () sur l'objet qui ne la « Supprimer cette ». COM objets fonctionnent fondamentalement cette façon, sauf qu'en plus ils sont référence compté avec la « supprimer ce » qui se produit lorsque le nombre de références est décrémenté à zéro.

Oui. Il devrait être parfaitement bien. « Ce » est juste un pointeur. Tout pointeur fera pour supprimer. Les informations sur la façon de supprimer un objet est contenue dans les dossiers de tas. Voici comment IUnknown :: Release () est généralement mis en œuvre dans les objets COM.

supprimer cela peut causer un problème lorsque vous avez des sous-classes de l'objet que vous supprimez. Rappelez-vous la construction commence de haut en bas et de suppression commence à partir du bas vers le haut. Donc, si ce supprimer est au milieu de la hiérarchie, vous essentiellement perdu tous les objets situés en dessous de cette classe particulière.

supprimer c'est très pratique lorsque vous implémentez un objet compté de référence, un exemple est les classes COM.

Lire pour une discussion similaire. Votre compréhension est juste en ce qu'elle fonctionne, est nécessaire et peut être dangereux car vous ne pouvez pas accéder à cette suite.

Oui
juridique Safe Non

Si vous héritez d'une classe de base et donné supprimer cette fonction dans la classe de base, en utilisant le pointeur de la classe dérivée provoque un accident. Par exemple:

class Base
{

    virtual void Release()
    {
        delete this;
    }

}

class Derived : public Base
{

    void Foo()
    {
        ...
    }

}

main()
{

    Base *ptrDerived = new Derived();
    ptrDerived->release();
    ptrDerived->Foo() //Crash

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top