Frage

Was ist die Verwendung destructor als privat zu haben?

War es hilfreich?

Lösung

Im Grunde wollen Sie jederzeit eine andere Klasse für den gesamten Lebenszyklus Ihrer Klasse Objekte verantwortlich sein, oder Sie haben Grund, die Zerstörung eines Objekts zu verhindern, können Sie die destructor privat machen.

Zum Beispiel, wenn Sie irgendeine Art von Referenzzählung, was tun, können Sie das Objekt (oder Manager, der „Freund“ ed war) verantwortlich für das Zählen der Anzahl von Referenzen auf sich selbst und es zu löschen, wenn die Zahl Hits Null. Ein privater dtor würde jemand verhindern sonst von ihm zu löschen, wenn es noch Verweise auf sie waren.

Für ein anderes Beispiel, was passiert, wenn Sie ein Objekt, das einen Manager hat (oder sich selbst), die es zerstören kann oder ablehnen, es zu zerstören auf andere Bedingungen im Programm abhängig, wie eine Datenbankverbindung offen ist oder eine Datei sein geschrieben. Sie könnten eine „request_delete“ Methode in der Klasse oder den Manager, der diese Bedingung überprüfen und es wird entweder löschen oder ablehnen, und gibt einen Status zu sagen, was es getan hat. Das ist viel flexibler, dass nur anrufen „löschen“.

Andere Tipps

Ein solches Objekt kann niemals auf dem Stapel erstellt werden. Immer auf dem Heap. Und Löschung hat über einen Freund oder ein Mitglied zu tun. Ein Produkt kann eine einzelne Objekthierarchie verwenden und einen benutzerdefinierten Speicher-Manager -. Solche Szenarien eine private dtor verwenden

#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;
}

Wenn Sie Benutzer nicht wollen, den destructor zugreifen zu können, das heißt, wollen Sie das Objekt nur durch andere Mittel zerstört werden.

http://blogs.msdn.com/larryosterman/ Archiv / 2005/07/01 / 434684.aspx gibt ein Beispiel, wo die Objektreferenz gezählt wird und nur durch das Objekt zerstört werden soll, selbst wenn Zählung auf Null geht.

COM verwendet diese Strategie für die Instanz zu löschen. COM macht die destructor private und bietet eine Schnittstelle für die Instanz zu löschen.

Hier ist ein Beispiel dafür, was eine Release-Methode aussehen würde.

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

ATL COM-Objekte sind ein gutes Beispiel für dieses Muster.

Zusätzlich zu den Antworten bereits hier; Private Konstruktoren und Destruktoren sind sehr nützlich, während ein Fabrik wo die erstellt Objekte sind erforderlich, auf dem Heap zugewiesen werden. Die Objekte würden in der Regel durch ein statisches Mitglied oder einen Freund erstellt / gelöscht werden. Beispiel für eine typische Nutzung:

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
}

Die Klasse kann nur durch sich selbst gelöscht werden. Nützlich, wenn Sie versuchen einige Referenz gezählt Objekt erstellen. Dann werden nur die Freigabe-Methode das Objekt löschen, möglicherweise hilft, Fehler zu vermeiden.

Ich weiß, dass Sie über privaten destructor fragen. Hier ist, wie ich geschützt diejenigen verwenden. Die Idee ist, dass Sie nicht Hauptklasse durch den Zeiger auf Klasse löschen möchten, die auf die Haupt zusätzliche Funktionalität hinzufügt.
Im Beispiel unten möchte ich nicht GuiWindow durch einen HandlerHolder Zeiger gelöscht werden.

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 ist falsch. Hier ist ein Beispiel für Objekt mit eigenem c-tor und d-tor auf Stapel erstellt (ich verwende statische Member-Funktion hier, aber es kann mit Freund-Funktion oder Freund Klasse als auch durchgeführt werden).

#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);
};

Dieser Code wird Ausgabe erzeugen: innerhalb PrivateCD :: TryMe, p._i = 8

Es könnte ein Weg sein, sich mit dem Problem in Windows zu behandeln, in denen jedes Modul einen anderen Haufen, wie die Debug Heap. Wenn das Problem nicht richtig gehandhabt wird, schlecht < a href = "https://stackoverflow.com/questions/443147/c-mix-new-delete-between-libs"> Dinge passieren kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top