Dengan C ++ 17 , shared_ptrdapat digunakan untuk mengelola array yang dialokasikan secara dinamis. The shared_ptrTemplate argumen dalam kasus ini harus T[N]atau T[]. Jadi, Anda bisa menulis
shared_ptr<int[]> sp(new int[10]);
Dari n4659, [util.smartptr.shared.const]
template<class Y> explicit shared_ptr(Y* p);
Membutuhkan: Y akan menjadi tipe yang lengkap. Ekspresi delete[] p, kapan Tadalah tipe array, atau delete p, ketika Tbukan tipe array, harus memiliki perilaku yang jelas, dan tidak akan membuang pengecualian.
...
Keterangan: Ketika Tmerupakan tipe array, konstruktor ini tidak akan berpartisipasi dalam resolusi yang berlebihan kecuali ekspresi delete[] pwell-formed dan baik Tadalah U[N]dan Y(*)[N]bisa dikonversi ke T*, atau Tadalah
U[]dan Y(*)[]bisa dikonversi ke T*. ...
Untuk mendukung ini, tipe anggota element_typesekarang didefinisikan sebagai
using element_type = remove_extent_t<T>;
Elemen array dapat diakses menggunakan operator[]
element_type& operator[](ptrdiff_t i) const;
Membutuhkan: get() != 0 && i >= 0 . Jika Tadalah U[N], i < N. ...
Keterangan: Ketika Tbukan tipe array, itu tidak ditentukan apakah fungsi anggota ini dideklarasikan. Jika dideklarasikan, tidak ditentukan jenis pengembaliannya, kecuali bahwa deklarasi (walaupun tidak harus definisi) dari fungsi harus dibentuk dengan baik.
Sebelum C ++ 17 , shared_ptrbisa tidak digunakan untuk mengelola array dialokasikan secara dinamis. Secara default, shared_ptrakan memanggil deleteobjek yang dikelola ketika tidak ada lagi referensi yang tersisa. Namun, ketika Anda mengalokasikan menggunakan new[]Anda perlu menelepon delete[], dan tidak delete, untuk membebaskan sumber daya.
Untuk menggunakan shared_ptrarray dengan benar, Anda harus menyediakan deleter khusus.
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
Buat shared_ptr sebagai berikut:
std::shared_ptr<int> sp(new int[10], array_deleter<int>());
Sekarang shared_ptrakan memanggil dengan benar delete[]ketika menghancurkan objek yang dikelola.
Deleter khusus di atas dapat diganti dengan
yang std::default_deletespesialisasi parsial untuk jenis berbagai
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
ekspresi lambda
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
Selain itu, kecuali jika Anda benar-benar perlu berbagi keanggotaan objek yang dikelola, a unique_ptrlebih cocok untuk tugas ini, karena ia memiliki spesialisasi parsial untuk jenis array.
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]
Perubahan yang diperkenalkan oleh C ++ Extensions for Fundamentals Library
Alternatif pra-C ++ 17 lain dari yang tercantum di atas disediakan oleh Spesifikasi Teknis Dasar-Dasar Perpustakaan , yang ditambahkan shared_ptruntuk memungkinkannya bekerja di luar kotak untuk kasus-kasus ketika ia memiliki berbagai objek. Draf shared_ptrperubahan yang dijadwalkan untuk TS ini saat ini dapat ditemukan di N4082 . Perubahan ini akan dapat diakses melalui std::experimentalnamespace, dan termasuk dalam <experimental/memory>header. Beberapa perubahan yang relevan untuk mendukung shared_ptrarray adalah:
- Definisi element_typeperubahan tipe anggota
typedef T element_type;
typedef typename remove_extent<T>::type element_type;
- Anggota operator[]sedang ditambahkan
element_type& operator[](ptrdiff_t i) const noexcept;
- Berbeda dengan unique_ptrspesialisasi parsial untuk array, keduanya shared_ptr<T[]>dan shared_ptr<T[N]>akan valid dan keduanya akan menghasilkan delete[]dipanggil pada array objek yang dikelola.
template<class Y> explicit shared_ptr(Y* p);
Membutuhkan : Yakan menjadi tipe yang lengkap. Ekspresi delete[] p, ketika Tadalah tipe array, atau delete p, ketika Tbukan tipe array, harus dibentuk dengan baik, harus memiliki perilaku yang jelas, dan tidak akan membuang pengecualian. Ketika Tadalah U[N], Y(*)[N]akan dikonversi ke T*; saat Tini U[], Y(*)[]akan dikonversi ke T*; jika tidak, Y*akan dapat dikonversi menjadi T*.
std::vector. Anda harus berhati-hati untuk menyebarkan array menggunakan referensi sehingga Anda tidak membuat salinannya. Sintaks untuk mengakses data lebih bersih daripada shared_ptr, dan mengubah ukurannya sangat sangat mudah. Dan Anda mendapatkan semua kebaikan STL jika Anda menginginkannya.