Apa yang terjadi
Saat Anda menulis, T t;
Anda membuat objek bertipe T
dengan durasi penyimpanan otomatis . Ini akan dibersihkan secara otomatis ketika keluar dari ruang lingkup.
Saat Anda menulis, new T()
Anda membuat objek bertipe T
dengan durasi penyimpanan dinamis . Itu tidak akan dibersihkan secara otomatis.
Anda harus meneruskan pointer ke sana delete
untuk membersihkannya:
Namun, contoh kedua Anda lebih buruk: Anda mendereferensi pointer, dan membuat salinan objek. Dengan cara ini Anda kehilangan pointer ke objek yang dibuat dengan new
, sehingga Anda tidak pernah bisa menghapusnya bahkan jika Anda mau!
Apa yang harus Anda lakukan
Anda harus memilih durasi penyimpanan otomatis. Butuh objek baru, cukup tulis:
A a; // a new object of type A
B b; // a new object of type B
Jika Anda memang membutuhkan durasi penyimpanan dinamis, simpan pointer ke objek yang dialokasikan dalam objek durasi penyimpanan otomatis yang menghapusnya secara otomatis.
template <typename T>
class automatic_pointer {
public:
automatic_pointer(T* pointer) : pointer(pointer) {}
// destructor: gets called upon cleanup
// in this case, we want to use delete
~automatic_pointer() { delete pointer; }
// emulate pointers!
// with this we can write *p
T& operator*() const { return *pointer; }
// and with this we can write p->f()
T* operator->() const { return pointer; }
private:
T* pointer;
// for this example, I'll just forbid copies
// a smarter class could deal with this some other way
automatic_pointer(automatic_pointer const&);
automatic_pointer& operator=(automatic_pointer const&);
};
automatic_pointer<A> a(new A()); // acts like a pointer, but deletes automatically
automatic_pointer<B> b(new B()); // acts like a pointer, but deletes automatically
Ini adalah ungkapan umum yang menggunakan nama RAII yang tidak terlalu deskriptif ( Resource Acquisition Is Inisialisasi ). Saat Anda memperoleh sumber daya yang perlu dibersihkan, Anda menempelkannya pada objek dengan durasi penyimpanan otomatis sehingga Anda tidak perlu khawatir untuk membersihkannya. Ini berlaku untuk sumber daya apa pun, baik itu memori, membuka file, koneksi jaringan, atau apa pun yang Anda suka.
Benda ini automatic_pointer
sudah ada dalam berbagai bentuk, saya baru saja memberikannya untuk memberi contoh. Kelas yang sangat mirip ada di perpustakaan standar yang disebut std::unique_ptr
.
Ada juga yang lama (pra-C ++ 11) bernama auto_ptr
tetapi sekarang sudah ditinggalkan karena memiliki perilaku penyalinan yang aneh.
Dan kemudian ada beberapa contoh yang lebih cerdas, seperti std::shared_ptr
, yang memungkinkan banyak pointer ke objek yang sama dan hanya membersihkannya ketika pointer terakhir dihancurkan.