Yanıtlar:
Temel olarak, başka bir sınıfın sınıfınızın nesnelerinin yaşam döngüsünden sorumlu olmasını istediğinizde veya bir nesnenin yok edilmesini önlemek için nedeniniz olduğunda, yıkıcıyı özel yapabilirsiniz.
Örneğin, bir çeşit referans sayma işi yapıyorsanız, kendisine referans sayısını saymaktan ve sayı sıfıra çarptığında onu silmek için nesnenin (veya "arkadaş" tarafından düzenlenmiş yöneticinin) sorumlu olmasını sağlayabilirsiniz. Özel bir dtor, hala referanslar olduğunda başkalarının onu silmesini önleyecektir.
Başka bir örnekte, yöneticinin (veya kendisinin) yok edebileceği veya program bağlantısının açık olması veya bir dosya yazılması gibi programdaki diğer koşullara bağlı olarak onu yok edebilecek bir nesneniz varsa ne olur? Sınıfta veya yöneticide bu koşulu kontrol edecek bir "request_delete" yöntemine sahip olabilirsiniz ve bu durum siler veya reddeder ve size ne yaptığını söyleyen bir durum döndürür. Bu sadece "sil" diyen çok daha esnektir.
Böyle bir nesne asla yığın üzerinde oluşturulamaz. Her zaman öbek üzerinde. Ve silme işlemi bir arkadaş veya üye aracılığıyla yapılmalıdır. Bir ürün tek bir Nesne hiyerarşisi ve özel bir bellek yöneticisi kullanabilir; bu tür senaryolar özel bir dtor kullanabilir.
#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;
}
Kullanıcıların yıkıcıya erişmesini istemediğinizde, nesnenin yalnızca başka yollarla yok edilmesini istersiniz.
http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx , nesnenin başvuru sayıldığı ve yalnızca sayı sıfıra gittiğinde nesnenin yok edilmesi gereken bir örnek verir.
COM, örneği silmek için bu stratejiyi kullanır. COM, yıkıcıyı özel yapar ve örneği silmek için bir arabirim sağlar.
İşte bir Release yönteminin nasıl görüneceğine bir örnek.
int MyRefCountedObject::Release()
{
_refCount--;
if ( 0 == _refCount )
{
delete this;
return 0;
}
return _refCount;
}
ATL COM nesneleri bu kalıbın en iyi örneğidir.
Burada bulunan cevaplara ek olarak; özel yapımcılar ve yıkıcılar , yaratılan nesnelerin öbek üzerinde tahsis edilmesi gereken bir fabrika uygularken oldukça kullanışlıdır . Nesneler genel olarak statik bir üye veya arkadaş tarafından oluşturulur / silinir. Tipik bir kullanım örneği:
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
}
Sınıf yalnızca kendiliğinden silinebilir. Referans sayılan bir nesne denemesi oluşturuyorsanız yararlıdır. Sonra nesneyi yalnızca bırakma yöntemi silebilir ve muhtemelen hatalardan kaçınmanıza yardımcı olur.
Özel yıkıcı hakkında soru sorduğunu biliyorum. Korumalı olanları nasıl kullanacağım. Ana fikir, ana sınıfı ekstra işlevsellik katan sınıfa işaretçi aracılığıyla silmek istemezsiniz.
Aşağıdaki örnekte GuiWindow'un bir HandlerHolder işaretçisi aracılığıyla silinmesini istemiyorum.
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 yanlış. İşte yığın üzerinde oluşturulan özel c-tor ve d-tor ile nesne örneği (Burada statik üye işlevi kullanıyorum, ancak arkadaş işlevi veya arkadaş sınıfı ile de yapılabilir).
#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);
};
Bu kod çıktı üretir: PrivateCD içinde :: TryMe, p._i = 8
Windows'ta her modülün Hata Ayıklama yığını gibi farklı bir yığın kullanabileceği sorunla başa çıkmanın bir yolu olabilir . Bu sorun doğru şekilde ele alınmazsa kötü şeyler olabilir.