C ++ 03
std::auto_ptr
- Mungkin salah satu yang asli menderita sindroma draf pertama hanya karena fasilitas pengumpulan sampah terbatas. Kelemahan pertama adalah bahwa ia memanggil delete
pemusnahan membuat mereka tidak dapat diterima untuk menampung array yang dialokasikan objek ( new[]
). Ini mengambil kepemilikan penunjuk sehingga dua penunjuk otomatis tidak boleh berisi objek yang sama. Tugas akan mentransfer kepemilikan dan mengatur ulang penunjuk otomatis rvalue ke penunjuk nol. Yang mungkin mengarah pada kelemahan terburuk; mereka tidak dapat digunakan dalam kontainer STL karena ketidakmampuan untuk disalin. Pukulan terakhir untuk setiap kasus penggunaan adalah mereka dijadwalkan untuk tidak digunakan lagi dalam standar C ++ berikutnya.
std::auto_ptr_ref
- Ini bukan penunjuk cerdas, ini sebenarnya adalah detail desain yang digunakan std::auto_ptr
untuk memungkinkan penyalinan dan penugasan dalam situasi tertentu. Secara khusus ini dapat digunakan untuk mengubah non-const std::auto_ptr
menjadi nilai l menggunakan trik Colvin-Gibbons yang juga dikenal sebagai konstruktor pemindahan untuk mentransfer kepemilikan.
Sebaliknya, mungkin std::auto_ptr
tidak benar-benar dimaksudkan untuk digunakan sebagai penunjuk cerdas tujuan umum untuk pengumpulan sampah otomatis. Sebagian besar pemahaman dan asumsi saya yang terbatas didasarkan pada Penggunaan Efektif Herb Sutter dari auto_ptr dan saya menggunakannya secara teratur meskipun tidak selalu dengan cara yang paling optimal.
C ++ 11
std::unique_ptr
- Ini adalah teman kita yang akan menggantinya std::auto_ptr
akan sangat mirip kecuali dengan perbaikan utama untuk memperbaiki kelemahan std::auto_ptr
seperti bekerja dengan array, perlindungan lvalue melalui konstruktor salinan pribadi, dapat digunakan dengan kontainer dan algoritma STL, dll. Karena itu overhead kinerja dan jejak memori terbatas, ini adalah kandidat yang ideal untuk menggantikan, atau mungkin lebih tepat digambarkan sebagai memiliki, petunjuk mentah. Karena "unik" menyiratkan hanya ada satu pemilik penunjuk seperti sebelumnya std::auto_ptr
.
std::shared_ptr
- Saya yakin ini didasarkan pada TR1 dan boost::shared_ptr
tetapi ditingkatkan untuk menyertakan aritmatika aliasing dan pointer juga. Singkatnya, ini membungkus referensi pointer pintar terhitung di sekitar objek yang dialokasikan secara dinamis. Karena "bersama" menyiratkan bahwa penunjuk dapat dimiliki oleh lebih dari satu penunjuk bersama ketika referensi terakhir dari penunjuk bersama terakhir keluar dari ruang lingkup maka objek akan dihapus dengan tepat. Ini juga aman untuk benang dan dapat menangani jenis yang tidak lengkap dalam banyak kasus. std::make_shared
dapat digunakan untuk membuat std::shared_ptr
alokasi heap dengan satu heap secara efisien menggunakan pengalokasi default.
std::weak_ptr
- Juga berdasarkan TR1 dan boost::weak_ptr
. Ini adalah referensi ke objek yang dimiliki oleh a std::shared_ptr
dan oleh karena itu tidak akan mencegah penghapusan objek jika jumlah std::shared_ptr
referensi turun ke nol. Untuk mendapatkan akses ke pointer mentah, pertama-tama Anda harus mengakses std::shared_ptr
by calling lock
yang akan mengembalikan kosong std::shared_ptr
jika pointer yang dimiliki telah kedaluwarsa dan sudah dimusnahkan. Ini terutama berguna untuk menghindari penghitungan referensi gantung yang tidak terbatas saat menggunakan beberapa petunjuk cerdas.
Dorongan
boost::shared_ptr
- Mungkin yang paling mudah digunakan dalam skenario yang paling bervariasi (STL, PIMPL, RAII, dll) ini adalah penunjuk cerdas terhitung yang dirujuk bersama. Saya telah mendengar beberapa keluhan tentang kinerja dan overhead dalam beberapa situasi tetapi saya pasti mengabaikannya karena saya tidak dapat mengingat apa argumennya. Rupanya itu cukup populer untuk menjadi objek C ++ standar yang tertunda dan tidak ada kelemahan atas norma mengenai petunjuk cerdas yang muncul di benak.
boost::weak_ptr
- Sama seperti deskripsi sebelumnya tentang std::weak_ptr
, berdasarkan implementasi ini, ini memungkinkan referensi yang tidak memiliki referensi untuk a boost::shared_ptr
. Anda tidak mengherankan memanggil lock()
untuk mengakses penunjuk bersama "kuat" dan harus memeriksa untuk memastikan itu valid karena bisa saja sudah dimusnahkan. Pastikan untuk tidak menyimpan penunjuk bersama yang dikembalikan dan membiarkannya keluar dari ruang lingkup segera setelah Anda selesai dengannya jika tidak, Anda akan langsung kembali ke masalah referensi siklik di mana jumlah referensi Anda akan hang dan objek tidak akan dimusnahkan.
boost::scoped_ptr
- Ini adalah kelas penunjuk cerdas sederhana dengan sedikit overhead yang mungkin dirancang untuk alternatif yang berkinerja lebih baik daripada boost::shared_ptr
saat dapat digunakan. Ini sebanding dengan std::auto_ptr
fakta bahwa itu tidak dapat digunakan dengan aman sebagai elemen dari wadah STL atau dengan banyak penunjuk ke objek yang sama.
boost::intrusive_ptr
- Saya belum pernah menggunakan ini, tetapi dari pemahaman saya, ini dirancang untuk digunakan saat membuat kelas yang kompatibel dengan penunjuk cerdas Anda sendiri. Anda perlu menerapkan penghitungan referensi sendiri, Anda juga perlu menerapkan beberapa metode jika Anda ingin kelas Anda menjadi generik, selanjutnya Anda harus menerapkan keamanan utas Anda sendiri. Sisi positifnya, ini mungkin memberi Anda cara yang paling sesuai untuk memilih dan memilih dengan tepat seberapa banyak atau sedikit "kecerdasan" yang Anda inginkan. intrusive_ptr
biasanya lebih efisien daripada shared_ptr
karena memungkinkan Anda memiliki satu alokasi heap per objek. (terima kasih Arvid)
boost::shared_array
- Ini boost::shared_ptr
untuk array. Pada dasarnya new []
,, operator[]
dan tentu saja delete []
dipanggang. Ini dapat digunakan dalam wadah STL dan sejauh yang saya tahu semuanya dapat boost:shared_ptr
dilakukan meskipun Anda tidak dapat menggunakannya boost::weak_ptr
dengan ini. Namun, Anda dapat menggunakan a boost::shared_ptr<std::vector<>>
untuk fungsionalitas serupa dan mendapatkan kembali kemampuan untuk menggunakan boost::weak_ptr
referensi.
boost::scoped_array
- Ini boost::scoped_ptr
untuk array. Seperti dengan boost::shared_array
semua kebaikan array yang diperlukan telah dimasukkan. Yang ini tidak dapat disalin sehingga tidak dapat digunakan dalam kontainer STL. Saya telah menemukan hampir di mana pun Anda ingin menggunakan ini, Anda mungkin bisa menggunakannya std::vector
. Saya tidak pernah menentukan mana yang sebenarnya lebih cepat atau memiliki overhead yang lebih sedikit tetapi array cakupan ini tampaknya jauh lebih tidak terlibat daripada vektor STL. Saat Anda ingin menyimpan alokasi di tumpukan, pertimbangkan boost::array
sebagai gantinya.
Qt
QPointer
- Diperkenalkan di Qt 4.0, ini adalah penunjuk pintar "lemah" yang hanya bekerja dengan QObject
dan kelas turunan, yang dalam kerangka kerja Qt hampir semuanya jadi itu sebenarnya bukan batasan. Namun ada batasan yaitu tidak menyediakan pointer yang "kuat" dan meskipun Anda dapat memeriksa apakah objek yang mendasari valid dengan isNull()
Anda dapat menemukan objek Anda sedang dimusnahkan tepat setelah Anda melewati pemeriksaan itu terutama di lingkungan multi-threaded. Qt orang menganggap ini usang, saya percaya.
QSharedDataPointer
- Ini adalah penunjuk cerdas "kuat" yang berpotensi sebanding dengan boost::intrusive_ptr
meskipun memiliki beberapa keamanan utas bawaan tetapi memerlukan Anda untuk menyertakan metode penghitungan referensi ( ref
dan deref
) yang dapat Anda lakukan dengan membuat subkelas QSharedData
. Seperti kebanyakan Qt, objek paling baik digunakan melalui pewarisan yang cukup dan subclassing semuanya tampaknya menjadi desain yang dimaksudkan.
QExplicitlySharedDataPointer
- Sangat mirip dengan QSharedDataPointer
kecuali itu tidak secara implisit memanggil detach()
. Saya akan menyebut versi 2.0 ini QSharedDataPointer
karena sedikit peningkatan kontrol tentang kapan tepatnya harus melepaskan setelah jumlah referensi turun ke nol tidak terlalu berharga untuk objek yang sama sekali baru.
QSharedPointer
- Penghitungan referensi atom, thread safe, pointer yang dapat dibagikan, penghapusan kustom (dukungan array), terdengar seperti segala sesuatu yang seharusnya menjadi pointer cerdas. Inilah yang terutama saya gunakan sebagai penunjuk pintar di Qt dan saya merasa sebanding dengan boost:shared_ptr
meskipun mungkin secara signifikan lebih banyak overhead seperti banyak objek di Qt.
QWeakPointer
- Apakah Anda merasakan pola yang berulang? Sama seperti std::weak_ptr
dan boost::weak_ptr
ini digunakan dalam hubungannya dengan QSharedPointer
saat Anda membutuhkan referensi antara dua penunjuk cerdas yang sebaliknya akan menyebabkan objek Anda tidak akan pernah dihapus.
QScopedPointer
- Nama ini juga harus terlihat akrab dan sebenarnya didasarkan pada boost::scoped_ptr
tidak seperti versi Qt dari petunjuk bersama dan lemah. Ini berfungsi untuk menyediakan penunjuk cerdas pemilik tunggal tanpa overhead QSharedPointer
yang membuatnya lebih cocok untuk kompatibilitas, kecuali kode aman, dan semua hal yang mungkin Anda gunakan std::auto_ptr
atau boost::scoped_ptr
untuk.