informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Kerugian dari pointer mentah:
delete
Melepaskan sumber daya, menyebabkan kebocoran sumber dayadelete
Program keluar secara normal sebelumnya (misalnya, jikaif
tengahreturn
) atau keluar secara tidak normal sebelum terlambatdelete
, menyebabkan kebocoran sumber dayaPada saat ini, petunjuk cerdas sangat dibutuhkan. Kata intelijen dari smart pointer terutama tercermin dalam kenyataan bahwa pengguna tidak perlu memperhatikan pelepasan sumber daya, karena smart pointer akan membantu Anda sepenuhnya mengelola pelepasan sumber daya. Ini akan memastikan bahwa tidak peduli bagaimana logika program berjalan , itu akan dijalankan secara normal atau menghasilkan pengecualian.Ketika sumber daya habis masa berlakunya (lingkup fungsi atau program berakhir), sumber daya tersebut akan dilepaskan.
Mari kita terapkan sendiri penunjuk cerdas sederhana
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T* ptr = nullptr) : mptr(ptr) {}
~CSmartPtr() { delete mptr; }
private:
T* mptr;
};
int main()
{
CSmartPtr<int> ptr(new int());
/*其它的代码...*/
/*
由于ptr是栈上的智能指针对象,不管是函数正常执行完,
还是运行过程中出现异常,栈上的对象都会自动调用析构函数,
在析构函数中进行了delete操作,保证释放资源
*/
return 0;
}
Oleh karena itu, karena karakteristik di atas, smart pointer umumnya ditentukan di stack. pada saat yang sama,Penunjuk cerdas adalah objek kelas , sebuah pointer diteruskan di konstruktor kelas ini, dan pointer yang diteruskan dilepaskan di destruktor.Karena jenis objek ini dialokasikan dan dilepaskan di tumpukan, maka objek tersebut akan dilepaskan secara otomatis ketika fungsi (atau program) kita berakhir.
Jadi, bisakah smart pointer didefinisikan di heap?MisalnyaCSmartPtr* p = new CSmartPtr(new int);
, kompilasi bisa lolos, tetapi definisinya di sinip
Meskipun ini adalah tipe penunjuk cerdas, pada dasarnya ini adalah penunjuk mentahp
Masih perlu melakukannya secara manualdelete
, itu kembali ke masalah yang kita hadapi dengan petunjuk kosong di awal, jadi jangan gunakan seperti ini
Tentu saja, smart pointer harus serupa dengan raw pointer, dan juga harus menyediakan fitur umum dari raw pointer.*
Dan->
Fungsi kelebihan kedua operator ini benar-benar sama dengan raw pointer saat digunakan.
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T* ptr = nullptr) : mptr(ptr) {}
~CSmartPtr() { delete mptr; }
T& operator*() { return *mptr; }
T* operator->() { return mptr; }
private:
T* mptr;
};
int main()
{
CSmartPtr<int> ptr(new int());
*ptr = 20; // operator*()一定要返回引用,这样才可以赋值
cout << *ptr << endl; // 20
class Test
{
public:
void test() { cout << "call Test::test()" << endl; }
};
CSmartPtr<Test> ptr2 = new Test();
(*ptr2).test(); // (*ptr2)取出Test对象,用对象调用方法
// operator->()返回的是一个指针,实现了用指针调用函数
// 即(ptr2.operator->()) -> test()
ptr2->test();
return 0;
}
Smart pointer yang diimplementasikan pada bagian sebelumnya sangat mirip dengan raw pointer biasa yang digunakan, namun masih terdapat masalah besar Lihat kode berikut:
CSmartPtr<int> p1(new int());
CSmartPtr<int> p2(p1); // 拷贝构造
Kode yang berjalan langsung mogok karena konstruktor penyalinan default melakukan penyalinan dangkal.p1
Danp2
memegang hal yang samanew int
sumber,p2
Penghancuran pertama-tama melepaskan sumber dayanya, lalup1
Ketika dirusak, ia menjadidelete
Penunjuk liar, program macet
Jadi, bagaimana cara mengatasi masalah yang disebabkan oleh penyalinan dangkal?menulis kembaliCSmartPtr
Lihatlah konstruktor salinan
CSmartPtr(const CSmartPtr<T>& src) { mptr = new T(*src.mptr); }
Namun, sekarang kodenya berjalan normal pada saat inip1
Danp2
Dua sumber daya berbeda dikelola. Jika pengguna tidak memahaminya, mereka akan salah mengira demikianp1
Danp2
Kelola sumber daya yang sama
Oleh karena itu, salah jika kita menulis copy konstruktor seperti ini
Jadi, bagaimana cara mengatasi masalah salinan dangkal dari smart pointer? Dua metode:Penunjuk cerdas tanpa penghitungan referensi, penunjuk cerdas dengan penghitungan referensi
Mari kita lihat bagian ini terlebih dahuluPointer cerdas tanpa penghitungan referensi
auto_ptr
(C++98, sekarang tidak digunakan lagi)scoped_ptr
(Meningkatkan perpustakaan)unique_ptr
(C++11, disarankan)Sertakan file header saat menggunakan:#include <memory>
Mari pertimbangkan kode ini terlebih dahulu
auto_ptr<int> ptr1(new int());
auto_ptr<int> ptr2(ptr1);
*ptr2 = 20;
cout << *ptr1 << endl;
Operasinya gagal. Mengapa?auto_ptr
Kode sumber
Anda dapat melihat bahwa konstruksi salinan akan memanggil objek yang masukrelease
metode, metode ini adalah dengan menempatkan_Right
Sumber daya yang ditunjuk dikembalikan ke yang baruauto_ptr
objek, dan pada saat yang sama_Right
(tuaauto_ptr
)dari_Myptr
mulainullptr
Singkatnya, ini adalah menempatkan yang lamaauto_ptr
Sumber daya yang ditunjuk diberikan kepada yang baruauto_ptr
Ditahan, yang lama disetel kenullptr
.Oleh karena itu, kode di atas digunakan*ptr1
Salah saja.(auto_ptr
Selalu biarkan penunjuk cerdas terakhir mengelola sumber daya)
Jadi,auto_ptr
Apakah bisa digunakan dalam container? Lihat kode berikut.
int main()
{
vector<auto_ptr<int>> vec;
vec.push_back(auto_ptr<int>(new int(10)));
vec.push_back(auto_ptr<int>(new int(20)));
vec.push_back(auto_ptr<int>(new int(30)));
cout << *vec[0] << endl; // 10
vector<auto_ptr<int>> vec2 = vec;
/* 这里由于上面做了vector容器的拷贝,
相当于容器中的每一个元素都进行了拷贝构造,
原来vec中的智能指针全部为nullptr了,
再次访问就成访问空指针了,程序崩溃
*/
cout << *vec[0] << endl; // 程序崩溃
return 0;
}
Oleh karena itu, ini tidak digunakan lagi di C++auto_ptr
, kecuali skenario penerapannya sangat sederhana.Danauto_ptr
Tidak digunakan lagi di C++11 dan dihapus seluruhnya di C++17
Meringkaskan:auto_ptr
Smart pointer tidak memiliki penghitungan referensi, sehingga menangani masalah penyalinan dangkal dengan menyalin langsung yang sebelumnyaauto_ptr
diatur kenullptr
, biarlah yang terakhir sajaauto_ptr
memegang sumber daya
Anda perlu menginstal perpustakaan Boost, yang menyertakan file header.#include <boost/scoped_ptr.hpp>
Siap digunakan
Lihatlahscoped_ptr
Kode sumber:
template<class T> class scoped_ptr
{
private:
scoped_ptr(scoped_ptr const&);
scoped_ptr& operator=(scoped_ptr const&);
...
};
dapat dilihatscoped_ptr
Konstruktor salinan dan fungsi penugasan keduanya diprivatisasi, sehingga objek tidak mendukung kedua operasi ini dan tidak dapat dipanggil, yang pada dasarnya mencegah terjadinya salinan dangkal.
Jadiscoped_ptr
Itu tidak dapat digunakan dalam wadah. Jika wadah menyalin atau memberikan nilai satu sama lain, hal itu akan menyebabkanscoped_ptr
Konstruktor salinan objek dan fungsi penugasan, kesalahan kompilasi
scoped_ptr
Danauto_ptr
Perbedaan: Dapat dijelaskan berdasarkan kepemilikan,auto_ptr
Kepemilikan sumber daya dapat dialihkan sesuka hati, sedangkanscoped_ptr
Kepemilikan tidak ditransfer (karena konstruktor penyalinan dan fungsi penugasan dinonaktifkan)
scoped_ptr
Umumnya tidak digunakan
Coba lihat duluunique_ptr
Bagian dari kode sumber:
template<class _Ty, class _Dx>
class unique_ptr
{
public:
/*提供了右值引用的拷贝构造函数*/
unique_ptr(unique_ptr&& _Right) { ... }
/*提供了右值引用的operator=赋值重载函数*/
unique_ptr& operator=(unique_ptr&& _Right) { ... }
/*
删除了unique_ptr的拷贝构造和赋值函数,
因此不能做unique_ptr智能指针对象的拷贝构造和赋值,
防止浅拷贝的发生
*/
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
};
Dilihat dari atas,unique_ptr
sedikitscoped_ptr
Hal yang sama dilakukan, yaitu fungsi konstruksi salinan dan penugasan yang kelebihan beban dinonaktifkan, dan pengguna dilarang untuk menggunakannyaunique_ptr
Lakukan konstruksi dan penetapan salinan eksplisit untuk mencegah terjadinya masalah salinan dangkal penunjuk pintar.
Karena tidak ada konstruktor penyalinan,unique_ptr<int> p1(new int()); unique_ptr<int> p2(p1);
Tentu saja itu salah
Tetapiunique_ptr
Menyediakan konstruktor penyalinan dan fungsi penugasan dengan parameter referensi nilai, yaitu,unique_ptr
Smart pointer dapat melakukan konstruksi salinan dan operasi penugasan melalui referensi nilai, atau menghasilkanunique_ptr
Tempat untuk benda-benda sementara, misunique_ptr
Sebagai nilai kembalian dari fungsi tersebut, kode contohnya adalah sebagai berikut:
// 示例1
unique_ptr<int> p1(new int());
unique_ptr<int> p2(move(p1)); // 使用了右值引用的拷贝构造
p2 = move(p1); // 使用了右值引用的operator=赋值重载函数
// 示例2
unique_ptr<int> test_uniqueptr()
{
unique_ptr<int> ptr(new int());
return ptr;
}
int main()
{
/*
此处调用test_uniqueptr函数,在return ptr代码处,
调用右值引用的拷贝构造和赋值函数
*/
unique_ptr<int> p = test_uniqueptr(); // 调用带右值引用的拷贝构造函数
p = test_uniqueptr(); // 调用带右值引用的operator=赋值重载函数
return 0;
}
Kemudian gunakanunique_ptr
Manfaatnya adalah pengguna dapat menggunakan sesuatu sepertiunique_ptr<int> p2(move(p1));
pernyataan tersebut, dapat dilihat dengan jelas bahwap1
Sumber daya yang ditransfer kep2
,p1
Tidak ada lagi sumber daya yang ditahanauto_ptr
Ini tidak akan secara eksplisitmove
Secara tertulis, maksudnya tidak jelas. Jika Anda tidak memahami lapisan yang mendasarinya, Anda akan salah menggunakannya.
Pada saat yang sama, dariunique_ptr
Seperti namanya, hanya ada satu smart pointer yang pada akhirnya merujuk pada suatu sumber daya. Oleh karena itu, disarankan untuk mengutamakan penggunaan smart pointer tanpa penghitungan referensi.unique_ptr
Petunjuk cerdas dengan penghitungan referensi terutama mencakupshared_ptr
Danweak_ptr
, dengan penghitungan referensikeuntunganArtinya, beberapa smart pointer dapat mengelola sumber daya yang sama. Jadi, apa yang dimaksud dengan smart pointer dengan penghitungan referensi?
Dengan penghitungan referensi: Cocokkan jumlah referensi untuk setiap sumber daya objek.
Ketika beberapa penunjuk cerdas diizinkan untuk menunjuk ke sumber daya yang sama, setiap penunjuk cerdas akan menambahkan 1 ke jumlah referensi sumber daya. Saat penunjuk cerdas dihancurkan, jumlah referensi sumber daya juga akan berkurang sebanyak 1, sehingga penunjuk pintar terakhir akan Ketika jumlah referensi suatu sumber daya berkurang dari 1 menjadi 0, ini berarti bahwa sumber daya tersebut dapat dilepaskan. Destruktor dari penunjuk pintar terakhir menangani pelepasan sumber daya.
Ambil contoh apa yang telah diterapkan sebelumnyaCSmartPtr
Lakukan modifikasi dan unggah kode secara langsung:
// 对资源进行引用计数的类
template<typename T>
class RefCnt
{
public:
RefCnt(T* ptr = nullptr) : mptr(ptr)
{
if (mptr != nullptr)
mcount = 1;
}
void addRef() { mcount++; } // 增加资源的引用计数
int delRef() { return --mcount; }
private:
T* mptr;
int mcount;
};
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T* ptr = nullptr) : mptr(ptr)
{
// 智能指针构造的时候给资源建立引用计数对象
mpRefCnt = new RefCnt<T>(mptr);
}
~CSmartPtr()
{
if (0 == mpRefCnt->delRef())
{
delete mptr;
mptr = nullptr;
}
}
// 实现拷贝构造
CSmartPtr(const CSmartPtr<T>& src)
:mptr(src.mptr), mpRefCnt(src.mpRefCnt)
{
if (mptr != nullptr)
mpRefCnt->addRef();
}
CSmartPtr<T>& operator=(const CSmartPtr<T>& src)
{
// 防止自赋值
if (this == &src)
return *this;
// 本身指向的资源减1
// 如果减1为0释放资源;如果减1不为0直接走
if (0 == mpRefCnt->delRef()) { delete mptr; }
mptr = src.mptr;
mpRefCnt = src.mpRefCnt;
mpRefCnt->addRef();
return *this;
}
T& operator*() { return *mptr; }
T* operator->() { return mptr; }
private:
T* mptr; // 指向资源的指针
RefCnt<T>* mpRefCnt; // 指向该资源引用计数对象的指针
};
// 那么现在就不会报错了,不会对同一个资源释放多次
CSmartPtr<int> ptr1(new int());
CSmartPtr<int> ptr2(ptr1);
CSmartPtr<int> ptr3;
ptr3 = ptr2;
*ptr1 = 20;
cout << *ptr2 << " " << *ptr3 << endl; // 20 20
Hal ini memungkinkan beberapa penunjuk cerdas untuk mengelola sumber daya yang sama.
Namun, petunjuk cerdas yang kami terapkan sekarang tidak aman untuk thread dan tidak dapat digunakan dalam skenario multi-thread.Diimplementasikan oleh Curryshared_ptr
Danweak_ptr
Ini aman untuk benang!
shared_ptr
:kuatSmart pointer (dapat mengubah jumlah referensi sumber daya)weak_ptr
:lemahPetunjuk cerdas (jangan mengubah jumlah referensi sumber daya)Apa yang kami terapkan di bagian sebelumnyaCSmartPtr
Juga merupakan penunjuk cerdas yang kuat (dapat mengubah jumlah referensi sumber daya)
Hal ini dapat dipahami seperti ini: Penunjuk cerdas yang lemah mengamati Petunjuk cerdas yang kuat Petunjuk cerdas yang kuatmengamati Sumber daya (memori)
Jadi,Masalah referensi silang penunjuk pintar yang kuat (referensi melingkar). lalu apa itu?Datang dan lihatlah
class B; // 前置声明类B
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
shared_ptr<B> _ptrb; // 指向B对象的智能指针
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
shared_ptr<A> _ptra; // 指向A对象的智能指针
};
int main()
{
shared_ptr<A> pa(new A()); // pa指向A对象,A的引用计数为1
shared_ptr<B> pb(new B()); // pb指向B对象,B的引用计数为1
pa->_ptrb = pb; // A对象的成员变量_ptrb也指向B对象,B的引用计数为2
pb->_ptra = pa; // B对象的成员变量_ptra也指向A对象,A的引用计数为2
cout << pa.use_count() << endl;
cout << pb.use_count() << endl;
return 0;
}
hasil operasi:
A()
B()
2
2
Seperti yang Anda lihat, A dan B tidak dirusak, yang berarti referensi silang akan menyebabkannyanew
Sumber daya yang keluar tidak dapat dilepaskan sehingga mengakibatkan kebocoran sumber daya!
menganalisa:
keluarmain
ruang lingkup fungsi,pa
Danpb
Dua objek lokal dihancurkan, dan jumlah referensi objek A dan objek B masing-masing berkurang dari 2 menjadi 1. Kondisi untuk melepaskan A dan B tidak dapat dipenuhi (kondisi untuk melepaskan adalah jumlah referensi A dan B berkurang ke 0), sehingga menyebabkan duanew
Objek A dan B yang keluar tidak bisa dilepas sehingga menyebabkan kebocoran memoriMasalah referensi silang penunjuk pintar yang kuat (referensi melingkar).
Solusi: Gunakan smart pointer yang kuat saat mendefinisikan objek, dan gunakan smart pointer yang lemah saat mereferensikan objek.
class B; // 前置声明类B
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
weak_ptr<B> _ptrb; // 指向B对象的弱智能指针(引用对象时,用弱智能指针)
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
weak_ptr<A> _ptra; // 指向A对象的弱智能指针(引用对象时,用弱智能指针)
};
int main()
{
// 定义对象时,用强智能指针
shared_ptr<A> pa(new A()); // pa指向A对象,A的引用计数为1
shared_ptr<B> pb(new B()); // pb指向B对象,B的引用计数为1
// A对象的成员变量_ptrb也指向B对象,B的引用计数为1,因为是弱智能指针,引用计数没有改变
pa->_ptrb = pb;
// B对象的成员变量_ptra也指向A对象,A的引用计数为1,因为是弱智能指针,引用计数没有改变
pb->_ptra = pa;
cout << pa.use_count() << endl; // 1
cout << pb.use_count() << endl; // 1
return 0;
}
hasil operasi:
A()
B()
1
1
~B()
~A()
bisa dilihat, keluarmain
ruang lingkup fungsi,pa
Danpb
Kedua objek lokal dihancurkan, dan jumlah referensi objek A dan objek B masing-masing dikurangi dari 1 menjadi 0, mencapai kondisi untuk melepaskan A dan B. Oleh karena itu,new
Objek A dan objek B yang keluar dihancurkan, sehingga masalah terpecahkan.Masalah referensi silang penunjuk pintar yang kuat (referensi melingkar).
dapat dilihat,weak_ptr
Smart pointer yang lemah tidak akan mengubah jumlah referensi sumber daya, artinya smart pointer yang lemah hanya mengamati apakah objek tersebut hidup (apakah jumlah referensinya 0), dan tidak dapat menggunakan sumber daya.
Lalu kalau saat ini, tambahkan di kelas Avoid testA() { cout << "非常好用的方法!!" << endl; }
Metode seperti itu menambah Bvoid func() { _ptra->testA(); }
Bolehkah memanggil metode ini?
*
Dan->
Fungsi operator yang kelebihan beban tidak dapat menggunakan fungsi yang mirip dengan pointer mentahLarutan:
class B; // 前置声明类B
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void testA() { cout << "非常好用的方法!!" << endl; }
weak_ptr<B> _ptrb; // 指向B对象的弱智能指针(引用对象时,用弱智能指针)
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
void func()
{
shared_ptr<A> sp = _ptra.lock(); // 提升方法,出函数作用域就自动析构了
if (sp != nullptr)
sp->testA();
}
weak_ptr<A> _ptra; // 指向A对象的弱智能指针(引用对象时,用弱智能指针)
};
int main()
{
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->_ptrb = pb;
pb->_ptra = pa;
cout << pa.use_count() << endl; // 1
cout << pb.use_count() << endl; // 1
pb->func();
return 0;
}
Meskipun
weak_ptr
tidak memiliki benda tersebut, tetapi dapat lewatlock()
metode mencoba untuk mendapatkan pointer ke objekshared_ptr
, jika benda tersebut masih hidup (yaitu ada benda lainshared_ptr
arahkan ke sana),lock()
akan mengembalikan pointer ke objekshared_ptr
; Jika tidak, nilai kosong akan dikembalikanshared_ptr
menggunakan
lock()
Skenario umum untuk metode adalah ketika akses sementara diperlukanweak_ptr
objek yang ditunjuknya, dan pada saat yang sama tidak ingin menambah jumlah umur objek tersebut
hasil operasi:
A()
B()
1
1
非常好用的方法!!
~B()
~A()
Pada titik ini Anda dapat melihat bahwa pemanggilannya benar!
Mari kita lihat satuMasalah keamanan thread saat mengakses objek bersama dari beberapa thread: Thread A dan thread B mengakses objek bersama. Jika thread A menghancurkan objek, thread B perlu memanggil metode anggota dari objek bersama. Pada saat ini, thread A mungkin telah selesai menghancurkan objek, dan thread B tidak akan melakukannya Jika Anda mencoba mengakses objek tersebut, kesalahan yang tidak terduga akan terjadi.
Pertama lihat kode berikut:
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void testA() { cout << "非常好用的方法!!" << endl; }
};
// 子线程
void handler01(A* q)
{
// 睡眠两秒,此时main主线程已经把A对象给delete析构掉了
std::this_thread::sleep_for(std::chrono::seconds(2));
q->testA();
}
// main线程
int main()
{
A* p = new A();
thread t1(handler01, p);
delete p;
//阻塞当前线程,直到调用join()的线程结束
t1.join();
return 0;
}
dalam eksekusiq->testA();
Ketika pernyataan ini dibuat,main
Objek yang dibagikan telah dihancurkan oleh thread, yang jelas tidak masuk akal.
Jika Anda ingin lulusq
Jika pointer ingin mengakses objek A, ia perlu menentukan apakah objek A masih hidup. Jika objek A masih hidup, panggiltestA
Tidak ada masalah dengan metode ini; jika objek A telah dirusak, panggiltestA
punya masalah!Artinyaq
Saat mengakses objek A, Anda perlu mendeteksi apakah objek A masih hidup. Bagaimana mengatasi masalah ini?
Mari kita lihat kode ini:
// 子线程
void handler01(weak_ptr<A> wp)
{
// 睡眠两秒
std::this_thread::sleep_for(std::chrono::seconds(2));
shared_ptr<A> sp = wp.lock();
if (sp != nullptr)
sp->testA();
else
cout << "A对象已经析构,不能再访问!" << endl;
}
// main线程
int main()
{
shared_ptr<A> p(new A());
thread t1(handler01, weak_ptr<A>(p));
t1.join();
return 0;
}
hasil operasi:
A()
非常好用的方法!!
~A()
Anda dapat melihatnya sedang berjalansp->testA();
,Karenamain
Utasnya memanggilt1.join()
Metode ini menunggu thread anak berakhirwp
luluslock
Berhasil dipromosikan menjadisp
Ubah kode di atas:
// 子线程
void handler01(weak_ptr<A> wp)
{
// 睡眠两秒
std::this_thread::sleep_for(std::chrono::seconds(2));
shared_ptr<A> sp = wp.lock();
if (sp != nullptr)
sp->testA();
else
cout << "A对象已经析构,不能再访问!" << endl;
}
// main线程
int main()
{
{
shared_ptr<A> p(new A());
thread t1(handler01, weak_ptr<A>(p));
t1.detach();
}
std::this_thread::sleep_for(std::chrono::seconds(3));
return 0;
}
hasil operasi:
A()
~A()
A对象已经析构,不能再访问!
Seperti yang Anda lihat, kami menetapkan cakupan dan juga menetapkant1
Untuk memisahkan thread, biarkan smart pointerp
Ketika A dirusak di luar ruang lingkup, itu akan dicetak saat iniA对象已经析构,不能再访问!
, itu adalahwp
luluslock
Gagal berhasil meningkatkan versi kesp
Di atas adalah masalah keamanan thread ketika multi-thread mengakses objek bersamashared_ptr
Danweak_ptr
Aplikasi yang khas.
Artikel referensi:Pemahaman mendalam tentang pointer cerdas C++