Question

A quoi sert d'avoir un destructeur en tant que disque privé?

Était-ce utile?

La solution

En gros, chaque fois que vous souhaitez qu'une autre classe soit responsable du cycle de vie des objets de votre classe ou que vous avez des raisons d'empêcher la destruction d'un objet, vous pouvez rendre le destructeur privé.

Par exemple, si vous effectuez une sorte de comptage de références, vous pouvez demander à l’objet (ou au responsable qui a été "ami") de compter le nombre de références à lui-même et de le supprimer frappe zéro. Un vendeur privé empêcherait quiconque d’en effacer tout contenu alors qu’il y avait encore des références.

Dans un autre cas, que se passe-t-il si un objet ayant un gestionnaire (ou lui-même) peut le détruire ou peut refuser de le détruire en fonction d'autres conditions du programme, telles qu'une connexion à une base de données ouverte ou un fichier en cours? écrit. Vous pourriez avoir un " request_delete " méthode de la classe ou du gestionnaire qui vérifie cette condition et supprime ou refuse et renvoie un statut indiquant ce qu’elle a fait. C’est beaucoup plus flexible que de simplement appeler "supprimer".

Autres conseils

Un tel objet ne peut jamais être créé sur la pile. Toujours sur le tas. Et la suppression doit être effectuée via un ami ou un membre. Un produit peut utiliser une seule hiérarchie d’objets et un gestionnaire de mémoire personnalisé. De tels scénarios peuvent utiliser un créateur privé.

#include <iostream>
class a {
    ~a() {}
    friend void delete_a(a* p);
};


void delete_a(a* p)  {
    delete p;
}

int main()
{
    a *p = new a;
    delete_a(p);

    return 0;
}

Si vous ne souhaitez pas que les utilisateurs accèdent au destructeur, c’est-à-dire que vous voulez que l’objet ne soit détruit que par d’autres moyens.

http://blogs.msdn.com/larryosterman/ archive / 2005/07/01 / 434684.aspx donne un exemple, où l'objet est compté en référence et ne doit être détruit que par l'objet lui-même lorsque le compte passe à zéro.

COM utilise cette stratégie pour supprimer l'instance. COM rend le destructeur privé et fournit une interface pour la suppression de l'instance.

Voici un exemple de ce à quoi une méthode Release ressemblerait.

int MyRefCountedObject::Release() 
{
 _refCount--;
 if ( 0 == _refCount ) 
 {
    delete this;
    return 0;
 }
 return _refCount;
}

Les objets COM ATL sont un excellent exemple de ce modèle.

Ajouter aux réponses déjà présentes ici; Les constructeurs et destructeurs privés sont très utiles pour implémenter une fabrique où le les objets doivent être alloués sur le tas. Les objets seraient, en général, créés / supprimés par un membre statique ou un ami. Exemple d'utilisation typique:

class myclass
{
public:
    static myclass* create(/* args */)  // Factory
    {
        return new myclass(/* args */);
    }

    static void destroy(myclass* ptr)
    {
        delete ptr;
    }
private:
    myclass(/* args */) { ... }         // Private CTOR and DTOR
    ~myclass() { ... }                  // 
}

int main ()
{
    myclass m;                          // error: ctor and dtor are private
    myclass* mp = new myclass (..);     // error: private ctor
    myclass* mp = myclass::create(..);  // OK
    delete mp;                          // error: private dtor
    myclass::destroy(mp);               // OK
}

La classe ne peut être supprimée que par elle-même. Utile si vous créez un essai d'objet de référence. Ensuite, seule la méthode de publication peut supprimer l'objet, ce qui peut éventuellement vous aider à éviter les erreurs.

Je sais que vous avez posé une question sur le destructeur privé. Voici comment j'utilise les protégés. L'idée est que vous ne voulez pas supprimer la classe principale via le pointeur vers la classe qui ajoute des fonctionnalités supplémentaires à la classe principale.
Dans l'exemple ci-dessous, je ne souhaite pas que GuiWindow soit supprimé via un pointeur HandlerHolder.

class Handler
{
public:
    virtual void onClose() = 0;
protected:
    virtual ~Handler();
};

class HandlerHolder
{
public:
    void setHandler( Handler* );
    Handler* getHandler() const;
protected:
    ~HandlerHolder(){}
private:
    Handler* handler_;
};

class GuiWindow : public HandlerHolder
{
public:
    void finish()
    {
        getHandler()->onClose();
    }

    virtual ~GuiWindow(){}
};

dirkgently a tort. Voici un exemple d’objet avec c-tor et d-tor privés créés sur une pile (j’utilise la fonction membre static ici, mais cela peut également être fait avec la fonction friend ou la classe friend).

#include <iostream>

class PrivateCD
{
private:
    PrivateCD(int i) : _i(i) {};
    ~PrivateCD(){};
    int _i;
public:
    static void TryMe(int i)
    {
        PrivateCD p(i);
        cout << "inside PrivateCD::TryMe, p._i = " << p._i << endl;
    };
};

int main()
{
    PrivateCD::TryMe(8);
};

Ce code produira une sortie: dans PrivateCD :: TryMe, p._i = 8

C’est peut-être un moyen de traiter le problème sous Windows, dans lequel chaque module peut utiliser un segment de mémoire différent, tel que le Déboguer tas. Si ce problème n'est pas traité correctement, mauvais < un href = "https://stackoverflow.com/questions/443147/c-mix-new-delete-between-libs"> des choses peuvent se produire.

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