Apakah std::make_unique
ada manfaat efisiensi seperti std::make_shared
?
Dibandingkan dengan membangun secara manual std::unique_ptr
:
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
c++
c++11
c++14
smart-pointers
unique-ptr
NFRCR
sumber
sumber
make_shared
ada efisiensi lebih dari sekadar menulis kode tangan panjang?make_shared
dapat mengalokasikan ruang untuk objek dan ruang untuk blok kontrol bersama dalam satu alokasi tunggal. Biaya dari itu adalah bahwa objek tidak dapat dialokasikan secara terpisah dari blok kontrol, jadi jika Anda menggunakanweak_ptr
banyak maka Anda mungkin berakhir menggunakan lebih banyak memori.Jawaban:
Motivasi di belakang
make_unique
terutama dua kali lipat:make_unique
aman untuk membuat temporari, sedangkan dengan penggunaan eksplisitnew
Anda harus mengingat aturan tentang tidak menggunakan temporari yang tidak disebutkan namanya.Penambahan
make_unique
akhirnya berarti kita dapat memberi tahu orang untuk 'tidak pernah' menggunakannew
daripada aturan sebelumnya untuk "'tidak pernah' digunakannew
kecuali ketika Anda membuatunique_ptr
".Ada juga alasan ketiga:
make_unique
tidak membutuhkan penggunaan tipe yang berlebihan.unique_ptr<T>(new T())
->make_unique<T>()
Tidak ada alasan yang melibatkan peningkatan efisiensi runtime seperti yang
make_shared
dilakukan (karena menghindari alokasi kedua, dengan biaya penggunaan memori puncak yang berpotensi lebih tinggi).* Diharapkan bahwa C ++ 17 akan menyertakan perubahan aturan yang berarti bahwa ini tidak lagi tidak aman. Lihat makalah komite C ++ P0400R0 dan P0145R3 .
sumber
std::unique_ptr
danstd::shared_ptr
itulah sebabnya kita dapat memberitahu orang-orang untuk "tidak pernah menggunakannew
."make_shared
dan begitumake_unique
juga bagian terakhir yang sebelumnya hilang.f
:f(unique_ptr<T>(new T), function_that_can_throw());
- mengutip jawaban: Compiler diperbolehkan untuk panggilan (dalam rangka):new T
,function_that_can_throw()
,unique_ptr<T>(...)
. Tentunya jikafunction_that_can_throw
benar-benar melempar maka Anda bocor.make_unique
mencegah kasus ini. Jadi, pertanyaan saya terjawab.std::make_unique
danstd::make_shared
apakah ada karena dua alasan:std::unique_ptr
ataustd::shared_ptr
konstruktor. (Lihat bagian Catatan di sini .)Ini bukan tentang efisiensi runtime. Ada sedikit tentang blok kontrol dan
T
yang dialokasikan sekaligus, tapi saya pikir itu lebih merupakan bonus dan sedikit motivasi untuk fungsi-fungsi ini ada.sumber
std::make_shared
akan memastikan bahwa setidaknya satu dari mereka dibungkus dengan smart pointer sebelum alokasi memori lainnya terjadi, karenanya tidak ada kebocoran.Alasan mengapa Anda harus menggunakan
std::unique_ptr(new A())
ataustd::shared_ptr(new A())
langsung bukannyastd::make_*()
tidak dapat mengakses konstruktor kelas diA
luar lingkup saat ini.sumber
Pertimbangkan pemanggilan fungsi
Misalkan baru
A()
berhasil, tetapi baruB()
melempar pengecualian: Anda menangkapnya untuk melanjutkan eksekusi normal program Anda. Sayangnya, standar C ++ tidak mengharuskan objek A dihancurkan dan memorinya tidak dapat dialokasikan: memori bocor secara diam-diam dan tidak ada cara untuk membersihkannya. Dengan membungkus A dan B ke dalamstd::make_uniques
Anda yakin kebocoran tidak akan terjadi:Intinya di sini adalah
std::make_unique<A>
danstd::make_unique<B>
sekarang menjadi objek sementara, dan pembersihan objek sementara ditentukan dengan benar dalam standar C ++: destruktor mereka akan dipicu dan memori dibebaskan. Jadi jika Anda bisa, selalu lebih suka mengalokasikan objek menggunakanstd::make_unique
danstd::make_shared
.sumber