util.smartptr.shared.const / 9 di C ++ 11:
Efek: Membangun objek shared_ptr yang memiliki objek p dan deleter d. Konstruktor kedua dan keempat harus menggunakan salinan a untuk mengalokasikan memori untuk penggunaan internal.
Konstruktor kedua dan keempat memiliki prototipe ini:
template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
Dalam konsep terbaru, util.smartptr.shared.const / 10 setara dengan tujuan kami:
Efek: Membangun objek shared_ptr yang memiliki objek p dan deleter d. Ketika T bukan tipe array, konstruktor pertama dan kedua mengaktifkan shared_from_ini dengan hal. Konstruktor kedua dan keempat harus menggunakan salinan a untuk mengalokasikan memori untuk penggunaan internal. Jika pengecualian dilemparkan, d (p) disebut.
Jadi pengalokasi digunakan jika ada kebutuhan untuk mengalokasikannya dalam memori yang dialokasikan. Berdasarkan standar saat ini dan pada laporan cacat yang relevan, alokasi tidak wajib tetapi diambil alih oleh komite.
Meskipun antarmuka shared_ptr
memungkinkan implementasi di mana tidak pernah ada blok kontrol dan semua shared_ptr
dan weak_ptr
dimasukkan ke dalam daftar tertaut, tidak ada implementasi seperti itu dalam praktiknya. Selain itu, kata-katanya telah dimodifikasi dengan asumsi, misalnya, bahwa kata use_count
itu dibagikan.
Deleter diperlukan untuk hanya bergerak yang dapat dibangun. Dengan demikian, tidak mungkin untuk memiliki beberapa salinan di shared_ptr
.
Orang dapat membayangkan implementasi yang menempatkan deleter dalam yang dirancang khusus shared_ptr
dan memindahkannya ketika spesial shared_ptr
dihapus. Walaupun implementasinya tampak sesuai, ini juga aneh, terutama karena blok kontrol mungkin diperlukan untuk jumlah penggunaan (mungkin mungkin tetapi bahkan lebih aneh untuk melakukan hal yang sama dengan jumlah penggunaan).
DRs yang relevan yang saya temukan: 545 , 575 , 2434 (yang mengakui bahwa semua implementasi menggunakan blok kontrol dan tampaknya menyiratkan bahwa kendala multi-threading agak mengamanatkannya), 2802 (yang mengharuskan deleter hanya bergerak konstruktif dan dengan demikian mencegah implementasi di mana deleter disalin di antara beberapa file shared_ptr
).
a
) untuk membatalkan alokasi memori itu. Yang menyiratkan beberapa penyimpanan salinan itua
. Tidak ada informasi tentang itu di [util.smartptr.shared.dest].Dari std :: shared_ptr kami memiliki:
Dan dari std :: mengalokasikan_bagikan, kami mendapatkan:
Jadi sepertinya std :: mengalokasikan_bagikan harus mengalokasikan
deleter
dengan AndaAlloc
.EDIT: Dan dari
n4810
§20.11.3.6 Pembuatan [util.smartptr. Shared.create][Tekankan semua milikku]
Jadi standar mengatakan yang
std::allocate_shared
harus digunakanAlloc
untuk blok kontrol.sumber
n4810
dan diperbarui jawabannya.make_shared
, bukan konstruktor itu sendiri. Tetap saja, saya bisa menggunakan anggota untuk deleter kecil.Saya percaya ini tidak ditentukan.
Berikut spesifikasi konstruktor yang relevan: [util.smartptr.shared.const] / 10
Sekarang, interpretasi saya adalah bahwa ketika implementasi membutuhkan memori untuk penggunaan internal, ia melakukannya dengan menggunakan
a
. Itu tidak berarti bahwa implementasi harus menggunakan memori ini untuk meletakkan semuanya. Misalnya, anggap ada implementasi aneh ini:Apakah implementasi ini "menggunakan salinan
a
untuk mengalokasikan memori untuk penggunaan internal"? Ya, benar. Tidak pernah mengalokasikan memori kecuali dengan menggunakana
. Ada banyak masalah dengan implementasi naif ini, tetapi katakanlah ia beralih ke menggunakan pengalokasi dalam semua tetapi kasus paling sederhana di manashared_ptr
dibangun langsung dari pointer dan tidak pernah disalin atau dipindahkan atau direferensikan dan tidak ada komplikasi lainnya. Intinya adalah, hanya karena kita gagal membayangkan implementasi yang valid tidak dengan sendirinya membuktikan bahwa itu tidak dapat secara teoritis ada. Saya tidak mengatakan bahwa implementasi seperti itu sebenarnya dapat ditemukan di dunia nyata, hanya saja standar itu tampaknya tidak secara aktif melarangnya.sumber
shared_ptr
untuk tipe kecil mengalokasikan memori pada stack. Dan tidak memenuhi persyaratan standarstd::move(__d)
, dan kembali keallocate
saat salinan diperlukan.