智能指针相关
零、预备知识右值表示不可寻址的临时数据值。根据C11标准右值分为纯右值如字面量、表达式结果和将亡值即将销毁的对象。 右值具有不可修改、无持久内存地址的特性右值引用、移动语义、完美转发https://learn.microsoft.com/zh-cn/cpp/cpp/rvalue-reference-declarator-amp-amp?viewmsvc-170一、unique_ptr#includeiostream using namespace std; templatetypename T class MyUniquePtr { private: T* ptr_; public: MyUniquePtr(T *pnullptr):ptr_(p){} ~MyUniquePtr() { delete ptr_; ptr_ nullptr; } MyUniquePtr(const MyUniquePtr) delete; MyUniquePtr operator(const MyUniquePtr) delete; MyUniquePtr(MyUniquePtr other) noexcept : ptr_(other.ptr_) { other.ptr_ nullptr; } MyUniquePtr operator(MyUniquePtr other) noexcept { if(this ! other) // { delete ptr_; // ptr_ other.ptr_; // other.ptr_ nullptr; // } return *this; } T operator*() { return *ptr_; } T* operator-() { return ptr_; } // T* get() const { return ptr_; } // }; void MyUniquePtr_demo() { MyUniquePtrint p1(new int(42)); MyUniquePtrint p2(new int(10)); coutp1: p1endl; coutp2: p2endl; MyUniquePtrint p3 std::move(p2); coutp1: p1endl; coutp2: p2endl; coutp3: p3endl; MyUniquePtrintp4(std::move(p3)); coutp1: p1endl; coutp2: p2endl; coutp3: p3endl; coutp4: p4endl; p2 std::move(p1); coutp1: p1endl; coutp2: p2endl; }二、shared_ptr#includeiostream using namespace std; templatetypename T class MySharedPtr { private: T* ptr_; int* ref_count; void Relese() { if(ref_count !nullptr) { --*ref_count; if(*ref_count 0) { delete ptr_; delete ref_count; } ptr_ nullptr; ref_count nullptr; } } public: MySharedPtr(T* p nullptr) : ptr_(p),ref_count(nullptr) { if(ptr_ ! nullptr) ref_count new int(1); } ~MySharedPtr() { Relese(); } MySharedPtr(const MySharedPtr other) { ptr_ other.ptr_; ref_count other.ref_count; if(ref_count ! nullptr) *ref_count; } MySharedPtr operator(const MySharedPtr other) { if(this ! other) { Relese(); ptr_ other.ptr_; ref_count other.ref_count; if(ref_count ! nullptr) *ref_count; } return *this; } T operator*() { return *ptr_; } T* operator-() { return ptr_; } T* get() const { return ptr_; } int use_count() const { return ref_count ! nullptr ? *ref_count : 0; } }; void test_shared_ptr() { // 1. 测试构造 MySharedPtrint p1(new int(100)); cout p1 count: p1.use_count() endl; // 预期: 1 // 2. 测试拷贝构造 MySharedPtrint p2 p1; cout p1 count: p1.use_count() endl; // 预期: 2 cout p2 count: p2.use_count() endl; // 预期: 2 // 3. 测试独立指针 MySharedPtrint p3(new int(200)); cout p3 count: p3.use_count() endl; // 预期: 1 // 4. 测试赋值运算符 (p3 放弃 200接管 100) p3 p1; // 此时原本的 200 应该被自动 delete cout p1 count: p1.use_count() endl; // 预期: 3 cout p3 count: p3.use_count() endl; // 预期: 3 }三、weak_ptr#includeiostream using namespace std; struct ControlBlock { int shared_count; int weak_count; }; templatetypename T class MyWeakPtr; templatetypename T class SharedPtr { private: ControlBlock *cb; T* ptr_; void Release() { if(cb ! nullptr) { --cb-shared_count; if(cb-shared_count 0) { delete ptr_; if(cb-weak_count 0) { delete cb; } } cb nullptr; ptr_ nullptr; } } public: SharedPtr(T* pnullptr) : ptr_(p) , cb(nullptr) { if(ptr_ ! nullptr) { cb new ControlBlock; cb-shared_count 1; cb-weak_count 0; } } ~SharedPtr() { Release(); } SharedPtr(const SharedPtr other) { ptr_ other.ptr_; cb other.cb; if(cb ! nullptr) cb-shared_count; } SharedPtr(const MyWeakPtrT wp) : ptr_(nullptr),cb(nullptr) { if(!wp.expired()) { ptr_ wp.ptr_; cb wp.cb; cb-shared_count; } } SharedPtr operator(const SharedPtr other) { if(this ! other) { Release(); ptr_ other.ptr_; cb other.cb; if(ptr_ ! nullptr) cb-shared_count; } return *this; } T operator*(){return *ptr_;} T* operator-(){return ptr_;} T* get() const { return ptr_; } int use_count() const { return cb ! nullptr ? cb-shared_count : 0; } friend class MyWeakPtrT; }; templatetypename T class MyWeakPtr { private: T* ptr_; ControlBlock *cb; void Release() { if(cb ! nullptr) { --cb-weak_count; if(cb-shared_count 0 cb-weak_count 0) { delete cb; } cb nullptr; } } public: T* operator-() delete; T operator*() delete; MyWeakPtr() : ptr_(nullptr), cb(nullptr) {} // 默认无参构造 MyWeakPtr(const SharedPtrT p) : ptr_(p.ptr_),cb(p.cb) { if(cb ! nullptr) cb-weak_count; } ~MyWeakPtr() { Release(); } MyWeakPtr(const MyWeakPtrT other) { ptr_ other.ptr_; cb other.cb; if(ptr_ ! nullptr) cb-weak_count; } MyWeakPtr operator(const MyWeakPtrT other) { if(this ! other) { Release(); ptr_ other.ptr_; cb other.cb; if(cb ! nullptr) cb-weak_count; } return *this; } MyWeakPtr operator(const SharedPtrT other) { Release(); ptr_ other.ptr_; cb other.cb; if(cb ! nullptr) cb-weak_count; return *this; } bool expired() const {return cb nullptr || cb-shared_count 0 ;} friend class SharedPtrT; SharedPtrT lock() const { if(expired()) return SharedPtrT(nullptr); return SharedPtrT(*this); } }; // --- 准备测试类 --- class Girl; // 前向声明 class Boy { public: string name; SharedPtrGirl girl_friend; // 强引用 Boy(string n) : name(n) { cout [Constructor] Boy name created.\n; } ~Boy() { cout [Destructor] Boy name destroyed.\n; } void setGirl(SharedPtrGirl g) { girl_friend g; } }; class Girl { public: string name; // --- 关键点这里如果用 SharedPtr 就会导致循环引用 --- MyWeakPtrBoy boy_friend; Girl(string n) : name(n) { cout [Constructor] Girl name created.\n; } ~Girl() { cout [Destructor] Girl name destroyed.\n; } void setBoy(SharedPtrBoy b) { boy_friend b; } }; // --- 测试函数 1基础功能与 lock --- void test_basic_and_lock() { cout \n--- Starting Basic and Lock Test ---\n; MyWeakPtrint wp; { SharedPtrint sp(new int(42)); wp sp; cout Shared count (sp): sp.use_count() endl; // 预期: 1 // 测试 lock() 成功 SharedPtrint sp_locked wp.lock(); if (sp_locked.get() ! nullptr) { cout Lock successful, value: *sp_locked endl; // 预期: 42 cout Shared count after lock: sp_locked.use_count() endl; // 预期: 2 } } // sp 离开作用域计数减为 0内存释放 // 测试 expired() 和 lock() 失败 if (wp.expired()) { cout Object has been destroyed (expired).\n; // 预期执行 } SharedPtrint sp_failed wp.lock(); if (sp_failed.get() nullptr) { cout Lock failed after object destruction.\n; // 预期执行 } cout --- Basic Test Finished ---\n; } // --- 测试函数 2循环引用打破测试 --- void test_circular_reference() { cout \n--- Starting Circular Reference Test ---\n; { SharedPtrBoy tom(new Boy(Tom)); SharedPtrGirl rose(new Girl(Rose)); tom-setGirl(rose); // Tom 强引用 Rose rose-setBoy(tom); // Rose 弱引用 Tom cout Tom shared_count: tom.use_count() endl; // 预期: 1 (Rose是弱引用) cout Rose shared_count: rose.use_count() endl; // 预期: 1 (Tom是强引用) cout Leaving inner scope...\n; } // 预期结果在这里应该看到 Tom 和 Rose 的 Destructor 被调用。 // 如果没有看到打印销毁信息说明你的 weak_ptr 没有成功打破循环引用。 cout --- Circular Reference Test Finished ---\n; }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2409200.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!