1. unique_ptr:这种智能指针是用于独占一份内存资源,一个资源也就只允许被一个unique_ptr占用。离开作用域后自动删除,无需显式调用delete。并且不能复制,只能转移。
原理实现:
template <typename T> class unique_ptr{ private: T* ptr; public: explicit unique_ptr(T* p) : ptr(p) { } //构造函数 unique_ptr(unique_ptr && other) noexcept: //移动构造函数 ptr(other.ptr) { other.ptr = nullptr; } unique_ptr& operator=(unique_ptr &&other) noexcept //重载移动赋值运算符 { if(this != &other) { delete ptr; //这里实际上有问题 ptr = other.ptr; other.ptr = nullptr; } return *this; }
//事实上,unique_ptr直接禁止了=操作,使用会直接报错,正确的转移行为是用std::move 。此外,拷贝构造函数也被禁用了。
//官方的转移: std::unique_ptr<T> ptr2 = std::move(ptr1); T& operator*() const {return *ptr;} //为什么返回值是&引用?因为这个值在外面需要被修改 T* operator->() const {return ptr;} //析构 ~unique_ptr() {delete ptr;} T* get() const {return ptr;} T* release() { T* temp = ptr; ptr = nullptr; return temp; //temp应该释放,realse本身不应该删除内容 }
2. shared_ptr 这种指针可以多个指针指向同一份资源,每多一个指针计数就+1,反之-1,计数为0时删除资源。
class ControlBlock{ public: int shared_count = 0; int weak_count = 0; }; //用于管理引用计数 weak_ptr也会用到 //shared_ptr简单实现 template<typename T> class sharedptr{ T* ptr = nullptr; ControlBlock* ctrl = nullptr; public: sharedptr(T* p = nullptr): ptr(p){ //构造函数 if(ptr){ ctrl = new ControlBlock(); ctrl->shared_count = 1; } }
//为什么要设置默认值p=nullptr?因为这样在声明新的指针时可以不指定类型,生成空指针 sharedptr(const sharedptr& other): ptr(other.ptr), ctrl(other.ctrl){ if(ctrl) ctrl->shared_count++; //只要有控制块,就应该增加计数 } ~sharedptr(){ if(ctrl) ctrl->shared_count--; if(ctrl->shared_count == 0) { delete ptr; if(ctrl->weak_count == 0) delete ctrl; } } T& operator*() {return *ptr;} T* operator->() {return ptr;} int count() const{ //获取指针计数 return ctrl ? ctrl->shared_count : 0;
} friend class Weakptr<T>; //weakptr需要使用sharedptr的成员,所以声明友元 };
weakptr需要用到对应的控制块和shared_count:
class weakptr{ T* ptr = nullpr; controlblock *ctrl = nullptr; public: weakptr() = default; //默认构造 weakptr默认构造的时候不指定内容 weakptr( const sharedptr<T>& shared) : ptr(shared.ptr) ctrl(shared.ctrl){ if(ctrl) weak_count++; } //从sharedptr上构造 ~weakptr() { if(ctrl){ ctrl->weak_count--; if(ctrl->shared_count==0 && ctrl->weak_coun==0) delete ctrl; } } // 检查指针是否有效 bool expired() const { return !ctrl || ctrl->shared_count == 0; } //通过lock() 获取对应的shared_ptr sharedptr<T> lock() const{ if(expired()) return sharedptr<T>; sharedptr<T> shared; //如果已经没有对应shared_ptr就要重新恢复一个出来 shared.ptr = ptr; shared.ctrl = ctrl; ctrl->shared_count++; return shared; } }
使用标准的智能指针时需要使用std::shared_ptr<int> ptr这样的格式。
标签:count,return,ctrl,c++,智能,shared,unique,ptr,指针 From: https://www.cnblogs.com/namezhyp/p/18686266