Jaki jest pożytek z posiadania destruktora jako prywatnego?

Jaki jest pożytek z posiadania destruktora jako prywatnego?

Author: yesraaj, 2009-03-10

9 answers

Zasadniczo, za każdym razem, gdy chcesz, aby jakaś inna klasa była odpowiedzialna za cykl życia obiektów twojej klasy, lub masz powód, aby zapobiec zniszczeniu obiektu, możesz uczynić Destruktor prywatnym.

Na przykład, jeśli robisz coś w rodzaju zliczania referencji, możesz mieć obiekt (lub menedżera, który był "przyjacielem"ed) odpowiedzialny za zliczanie liczby referencji do siebie i usunąć go, gdy liczba osiągnie zero. Prywatny dtor uniemożliwiłby innym od usunięcia go, gdy były jeszcze odniesienia do niego.

Dla innej instancji, co zrobić, jeśli masz obiekt z menedżerem (lub samym), który może go zniszczyć lub może odmówić zniszczenia w zależności od innych warunków w programie, takich jak otwarte połączenie z bazą danych lub zapisanie pliku. Możesz mieć metodę "request_delete" w klasie lub Menedżerze, która sprawdzi ten warunek i usunie lub odrzuci i zwróci status informujący o tym, co zrobiła. To jest o wiele bardziej elastyczne niż po prostu wywołanie "Usuń".

 182
Author: Paul Tomblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-15 06:54:31

Taki obiekt nie może być utworzony na stosie. Zawsze na stosie. A usunięcie musi zostać dokonane za pośrednictwem znajomego lub członka. Produkt może używać jednej hierarchii obiektów i niestandardowego Menedżera pamięci -- takie scenariusze mogą używać prywatnego dtor.

#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;
}
 76
Author: dirkgently,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-11 09:50:15

Jeśli nie chcesz, aby użytkownicy mieli dostęp do destruktora, tzn. chcesz, aby obiekt został zniszczony tylko innymi środkami.

Http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx podaje przykład, w którym obiekt jest liczony jako reference i powinien być niszczony przez sam obiekt tylko wtedy, gdy zliczanie idzie do zera.

 45
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-10 19:03:14

COM używa tej strategii do usuwania instancji. COM czyni Destruktor prywatnym i zapewnia interfejs do usuwania instancji.

Oto przykład jak wyglądałaby metoda Release.

int MyRefCountedObject::Release() 
{
 _refCount--;
 if ( 0 == _refCount ) 
 {
    delete this;
    return 0;
 }
 return _refCount;
}
Obiekty ATL COM są doskonałym przykładem tego wzorca.
 18
Author: Vinay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-11 01:14:16

Dodanie do odpowiedzi już tutaj obecnych; prywatne konstruktory i destruktory są bardzo przydatne podczas implementacji factory gdzie utworzone obiekty muszą być przydzielone na stercie. Obiekty te byłyby ogólnie tworzone/usuwane przez statycznego członka lub przyjaciela. Przykład typowego użycia:

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
}
 9
Author: nav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-22 09:07:26

Klasa może zostać usunięta tylko sama. Przydatne, jeśli tworzysz jakiś obiekt z liczeniem referencji. Wtedy tylko metoda release może usunąć obiekt, co może pomóc uniknąć błędów.

 7
Author: Roland Rabien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-10 19:03:49

Wiem, że pytałeś o prywatnego niszczyciela. Oto, jak używam chronionych. Chodzi o to, że nie chcesz usuwać głównej klasy za pomocą wskaźnika do klasy, która dodaje dodatkową funkcjonalność do głównej.
W poniższym przykładzie nie chcę, aby GuiWindow był usuwany przez wskaźnik 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(){}
};
 3
Author: Mykola Golubyev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-11 14:08:50

Dirkgently jest w błędzie. Oto przykład obiektu z prywatnymi c-tor I d-tor utworzonymi na stosie(używam tutaj statycznej funkcji member, ale można to zrobić również za pomocą funkcji friend lub friend class).

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

Ten kod wygeneruje wyjście: inside PrivateCD:: TryMe, p. _i = 8

 3
Author: misicd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-10 09:53:55

Może to być sposób na rozwiązanie problemu w systemie Windows, w którym każdy moduł może używać innej sterty, takiej jak sterta Debugowania . Jeśli problem nie został poprawnie rozwiązany bad rzeczy mogą się zdarzyć.

 2
Author: Jared Oberhaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:08