Saya dengar auto_ptr
sudah tidak digunakan lagi di C ++ 11. Apa alasannya ini?
Saya juga ingin mengetahui perbedaan antara auto_ptr
dan shared_ptr
.
c++
c++11
smart-pointers
auto-ptr
brett
sumber
sumber
Jawaban:
Pengganti langsung untuk
auto_ptr
(atau yang paling dekat dengan salah satunya) adalahunique_ptr
. Sejauh "masalah" berjalan, itu cukup sederhana:auto_ptr
mentransfer kepemilikan ketika sudah ditetapkan.unique_ptr
juga mentransfer kepemilikan, tetapi berkat kodifikasi semantik pemindahan dan keajaiban referensi nilai r, hal itu dapat dilakukan secara lebih alami. Ini juga "cocok" dengan pustaka standar lainnya secara jauh lebih baik (meskipun, dalam keadilan, beberapa di antaranya berkat sisa pustaka yang berubah untuk mengakomodasi semantik bergerak alih-alih selalu membutuhkan penyalinan).Perubahan nama juga (IMO) merupakan hal yang disambut baik -
auto_ptr
tidak benar-benar memberi tahu Anda banyak tentang apa yang coba diotomatiskan, sedangkanunique_ptr
deskripsi yang cukup masuk akal (jika singkat) tentang apa yang disediakan.sumber
auto_ptr
nama: auto menyarankan otomatis seperti dalam variabel otomatis, dan ini mengacu pada satu hal yangauto_ptr
dilakukan: menghancurkan sumber daya yang dikelola di destruktornya (ketika keluar dari ruang lingkup).auto_ptr
: open-std.org/jtc1/sc22/wg21/docs/papers/2005/…std::sort
tidak memiliki spesialisasi untukunique_ptr
. Sebaliknya itu ditentukan ulang untuk tidak pernah menyalin. Jadiauto_ptr
sebenarnya tidak bekerja dengan modernsort
. Namun C ++ 98/03sort
adalah hanya sebuah contoh algoritma di sini: Setiap algoritma generik (std-disediakan atau pengguna tertulis) yang mengasumsikan bahwa sintaks copy memiliki copy semantik kemungkinan akan memiliki kesalahan run-time jika digunakan denganauto_ptr
, karenaauto_ptr
diam-diam bergerak dengan sintaks salin . Masalahnya jauh lebih besar dari sekadarsort
.Saya menemukan jawaban yang ada bagus, tetapi dari PoV petunjuknya. IMO, jawaban yang ideal harus memiliki jawaban perspektif pengguna / programmer.
Hal pertama yang pertama (seperti yang ditunjukkan oleh Jerry Coffin dalam jawabannya)
shared_ptr: Jika Anda khawatir tentang membebaskan sumber daya / memori DAN jika Anda memiliki lebih dari satu fungsi yang dapat menggunakan objek SETIAP kali, maka gunakan shared_ptr.
Menurut DIFFERENT-Times, pikirkan situasi di mana object-ptr disimpan dalam beberapa struktur data dan kemudian diakses. Beberapa utas, tentu saja adalah contoh lain.
unique_ptr: Jika semua yang Anda khawatirkan adalah mengosongkan memori, dan akses ke objek adalah SEQUENTIAL, maka gunakan unique_ptr.
Dengan SEQUENTIAL, maksud saya, pada titik mana pun objek akan diakses dari satu konteks. Misalnya benda yang dibuat, dan digunakan segera setelah dibuat oleh pencipta. Setelah pembuatan, objek disimpan dalam struktur data PERTAMA . Kemudian salah satu objek dihancurkan setelah SATU struktur data atau dipindahkan ke struktur data KEDUA .
Dari baris ini, saya akan merujuk shared / unique _ptr sebagai smart-pointers. (auto_ptr juga merupakan smart-pointer TETAPI karena kekurangan dalam desainnya, yang membuatnya tidak digunakan lagi, dan yang menurut saya akan saya tunjukkan di baris berikutnya, mereka tidak boleh dikelompokkan dengan smart-pointer.)
Dari tautan: http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
Jenis tugas yang didukung oleh unqiue_ptr
Dari: http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
Jenis tugas yang didukung oleh auto_ptr
Sekarang datang ke alasan MENGAPA tugas menyalin itu sendiri sangat tidak disukai, saya memiliki teori ini:
Perilaku yang tidak diinginkan benar-benar tidak disukai dan karenanya tidak menyukai auto_ptr.
(Untuk 3.1415926536% programmer yang dengan sengaja ingin mentransfer kepemilikan C ++ 11 memberi mereka std :: move (), yang membuat niat mereka sangat jelas bagi semua magang yang akan membaca dan memelihara kode.)
sumber
auto_ptr
nilai menunjuk ke objek yang sama (karena mereka tidak memberikan kepemilikan bersama, yang pertama mati akan meninggalkan yang lain dengan warisan yang mematikan; ini juga berlaku untukunique_ptr
penggunaan), dapatkah Anda menyarankan apa yang dimaksudkan di yang tersisa 96.8584073465% dari semua penggunaan?*a=*b;
Di sini hanya nilai b yang disalin ke a. Semoga Kepemilikan a dan b tetap dimiliki oleh orang yang sama. Anda menyebutkan seperti kepemilikan akan ditransfer. Bagaimana jadinya?auto_ptr
objek itu sendiri. Menugaskan ke / dari nilai menunjuk ke tidak akan berpengaruh pada, atau relevansi dengan, kepemilikan. Saya harap Anda tidak masih menggunakanauto_ptr
?shared_ptr
dapat disimpan di dalam wadah.auto_ptr
tidak bisa.BTW
unique_ptr
benar-benarauto_ptr
pengganti langsung , ini menggabungkan fitur terbaik dari keduanyastd::auto_ptr
danboost::scoped_ptr
.sumber
Namun yang lain menjelaskan perbedaannya ....
Secara fungsional, C ++ 11
std::unique_ptr
adalah "tetap"std::auto_ptr
: keduanya cocok ketika - pada titik waktu mana pun selama eksekusi - harus ada satu pemilik smart-pointer untuk objek yang diarahkan ke.Perbedaan krusial adalah dalam konstruksi salinan atau penugasan dari penunjuk cerdas lain yang tidak kedaluwarsa, yang ditunjukkan pada
=>
baris di bawah ini:std::auto_ptr<T> ap(...); std::auto_ptr<T> ap2(get_ap_to_T()); // take expiring ownership => std::auto_ptr<T> ap3(ap); // take un-expiring ownership ala ap3(ap.release()); ap->xyz; // oops... can still try to use ap, expecting it to be non-NULL std::unique_ptr<T> up(...); std::unique_ptr<T> up2(get_up_to_T()); // take expiring ownership => std::unique_ptr<T> up3(up); // COMPILE ERROR: can't take un-expiring ownership => std::unique_ptr<T> up4(std::move(up)); // EXPLICIT code allowed => std::unique_ptr<T> up4(up.release()); // EXPLICIT code allowed
Di atas,
ap3
diam-diam "mencuri" kepemilikan*ap
, meninggalkanap
set ke anullptr
, dan masalahnya adalah itu bisa terjadi terlalu mudah, tanpa programmer memikirkan keamanannya.Misalnya, jika a
class
/struct
memilikistd::auto_ptr
anggota, maka membuat salinan sebuah instance akanrelease
membuat pointer dari instance tersebut akan disalin: itu semantik yang aneh dan sangat membingungkan karena biasanya menyalin sesuatu tidak akan mengubahnya. Sangat mudah bagi penulis class / struct untuk mengabaikan rilis pointer ketika bernalar tentang invariants dan state, dan akibatnya secara tidak sengaja mencoba untuk dereferensi smart-pointer sementara null, atau hanya tidak memiliki akses / kepemilikan yang diharapkan dari data yang diarahkan ke.sumber
auto_ptr tidak dapat digunakan dalam penampung STL karena memiliki konstruktor salinan yang tidak memenuhi persyaratan penampung CopyConstructible . unique_ptr tidak mengimplementasikan konstruktor salinan, jadi container menggunakan metode alternatif. unique_ptr dapat digunakan dalam container dan lebih cepat untuk algoritme std daripada shared_ptr.
#include <iostream> #include <type_traits> #include <vector> #include <memory> using namespace std; int main() { cout << boolalpha; cout << "is_copy_constructible:" << endl; cout << "auto_ptr: " << is_copy_constructible< auto_ptr<int> >::value << endl; cout << "unique_ptr: " << is_copy_constructible< unique_ptr<int> >::value << endl; cout << "shared_ptr: " << is_copy_constructible< shared_ptr<int> >::value << endl; vector<int> i_v; i_v.push_back(1); cout << "i_v=" << i_v[0] << endl; vector<int> i_v2=i_v; cout << "i_v2=" << i_v2[0] << endl; vector< unique_ptr<int> > u_v; u_v.push_back(unique_ptr<int>(new int(2))); cout << "u_v=" << *u_v[0] << endl; //vector< unique_ptr<int> > u_v2=u_v; //will not compile, need is_copy_constructible == true vector< unique_ptr<int> > u_v2 =std::move(u_v); // but can be moved cout << "u_v2=" << *u_v2[0] << " length u_v: " <<u_v.size() << endl; vector< shared_ptr<int> > s_v; shared_ptr<int> s(new int(3)); s_v.push_back(s); cout << "s_v=" << *s_v[0] << endl; vector< shared_ptr<int> > s_v2=s_v; cout << "s_v2=" << *s_v2[0] << endl; vector< auto_ptr<int> > a_v; //USAGE ERROR return 0; } >cxx test1.cpp -o test1 test1.cpp: In function âint main()â: test1.cpp:33:11: warning: âauto_ptrâ is deprecated (declared at /apps/hermes/sw/gcc/gcc-4.8.5/include/c++/4.8.5/backward/auto_ptr.h:87) [-Wdeprecated-declarations] vector< auto_ptr<int> > a_v; //USAGE ERROR ^ >./test1 is_copy_constructible: auto_ptr: false unique_ptr: false shared_ptr: true i_v=1 i_v2=1 u_v=2 s_v=3 s_v2=3
sumber