Jawaban:
Pada dasarnya, setiap kali Anda ingin beberapa kelas lain bertanggung jawab atas siklus hidup objek kelas Anda, atau Anda memiliki alasan untuk mencegah penghancuran suatu objek, Anda dapat menjadikan destruktor itu pribadi.
Misalnya, jika Anda melakukan semacam penghitungan referensi, Anda dapat memiliki objek (atau pengelola yang "teman" red) yang bertanggung jawab untuk menghitung jumlah referensi itu sendiri dan menghapusnya ketika jumlahnya mencapai nol. Seorang dtor pribadi akan mencegah orang lain menghapusnya ketika masih ada referensi untuk itu.
Untuk contoh lain, bagaimana jika Anda memiliki objek yang memiliki manajer (atau dirinya sendiri) yang dapat menghancurkannya atau mungkin menolak untuk menghancurkannya tergantung pada kondisi lain dalam program, seperti koneksi database yang terbuka atau file yang sedang ditulis. Anda bisa memiliki metode "request_delete" di kelas atau manajer yang akan memeriksa kondisi itu dan itu akan menghapus atau menolak, dan mengembalikan status yang memberi tahu Anda apa yang telah dilakukannya. Itu jauh lebih fleksibel daripada hanya memanggil "hapus".
Objek seperti itu tidak pernah dapat dibuat di stack. Selalu di tumpukan. Dan penghapusan harus dilakukan melalui teman atau anggota. Suatu produk dapat menggunakan hierarki objek tunggal dan manajer memori khusus - skenario tersebut dapat menggunakan dtor pribadi.
#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;
}
Ketika Anda tidak ingin pengguna mengakses destruktor, yaitu, Anda ingin objek hanya dihancurkan melalui cara lain.
http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx memberikan contoh, di mana referensi objek dihitung dan hanya boleh dimusnahkan oleh objek itu sendiri ketika hitungannya menjadi nol.
COM menggunakan strategi ini untuk menghapus instance. COM menjadikan destructor sebagai pribadi dan menyediakan antarmuka untuk menghapus instance.
Berikut ini adalah contoh dari bagaimana metode Release akan terlihat.
int MyRefCountedObject::Release()
{
_refCount--;
if ( 0 == _refCount )
{
delete this;
return 0;
}
return _refCount;
}
Objek ATL COM adalah contoh utama dari pola ini.
Menambah jawaban sudah ada di sini; konstruktor dan destruktor pribadi cukup berguna saat menerapkan pabrik di mana objek yang dibuat harus dialokasikan pada heap. Objek akan, secara umum, dibuat / dihapus oleh anggota statis atau teman. Contoh penggunaan tipikal:
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
}
Kelas hanya dapat dihapus dengan sendirinya. Berguna jika Anda membuat beberapa percobaan referensi objek yang dihitung. Maka hanya metode pelepasan yang dapat menghapus objek, mungkin membantu Anda menghindari kesalahan.
Saya tahu Anda bertanya tentang destruktor pribadi. Inilah cara saya menggunakan yang dilindungi. Idenya adalah Anda tidak ingin menghapus kelas utama melalui pointer ke kelas yang menambahkan fungsionalitas tambahan ke utama.
Dalam contoh di bawah ini saya tidak ingin GuiWindow dihapus melalui pointer 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 salah. Berikut adalah contoh objek dengan private c-tor dan d-tor yang dibuat pada stack (Saya menggunakan fungsi anggota statis di sini, tetapi dapat dilakukan dengan fungsi teman atau kelas teman juga).
#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);
};
Kode ini akan menghasilkan keluaran: di dalam PrivateCD :: TryMe, p._i = 8