Dengan C ++ 17 , shared_ptr
dapat digunakan untuk mengelola array yang dialokasikan secara dinamis. The shared_ptr
Template 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 T
adalah tipe array, atau delete p
, ketika T
bukan tipe array, harus memiliki perilaku yang jelas, dan tidak akan membuang pengecualian.
...
Keterangan: Ketika T
merupakan tipe array, konstruktor ini tidak akan berpartisipasi dalam resolusi yang berlebihan kecuali ekspresi delete[] p
well-formed dan baik T
adalah U[N]
dan Y(*)[N]
bisa dikonversi ke T*
, atau T
adalah
U[]
dan Y(*)[]
bisa dikonversi ke T*
. ...
Untuk mendukung ini, tipe anggota element_type
sekarang 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 T
adalah U[N]
, i < N
. ...
Keterangan: Ketika T
bukan 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_ptr
bisa tidak digunakan untuk mengelola array dialokasikan secara dinamis. Secara default, shared_ptr
akan memanggil delete
objek 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_ptr
array 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_ptr
akan memanggil dengan benar delete[]
ketika menghancurkan objek yang dikelola.
Deleter khusus di atas dapat diganti dengan
yang std::default_delete
spesialisasi 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_ptr
lebih 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_ptr
untuk memungkinkannya bekerja di luar kotak untuk kasus-kasus ketika ia memiliki berbagai objek. Draf shared_ptr
perubahan yang dijadwalkan untuk TS ini saat ini dapat ditemukan di N4082 . Perubahan ini akan dapat diakses melalui std::experimental
namespace, dan termasuk dalam <experimental/memory>
header. Beberapa perubahan yang relevan untuk mendukung shared_ptr
array adalah:
- Definisi element_type
perubahan 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_ptr
spesialisasi 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 : Y
akan menjadi tipe yang lengkap. Ekspresi delete[] p
, ketika T
adalah tipe array, atau delete p
, ketika T
bukan tipe array, harus dibentuk dengan baik, harus memiliki perilaku yang jelas, dan tidak akan membuang pengecualian. Ketika T
adalah U[N]
, Y(*)[N]
akan dikonversi ke T*
; saat T
ini 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.