C++手撕 shared_ptr
智能指针的前置知识可以参考 智能指针点这里 话不多说,上代码
#include<iostream>
using namespace std;class Count//引用计数
{
public:Count(){ num = 1;}void add(){ num++; }//引用计数增加void sub(){ num--; }//引用计数减少int get(){ return num; }//获取当前引用计数
private:int num = 0;
};template<typename T>
class smartPtr
{
public:smartPtr(T* ptr = nullptr)//构造函数:p(ptr){if (p) cnt = new Count();//如果p不为空,则创建引用计数类的指针else cnt = nullptr;}~smartPtr()//析构函数{if (cnt){cnt->sub();//引用计数 -1if (cnt->get() == 0)//如果引用计数减为0,释放资源{delete p;p = nullptr;delete cnt;cnt = nullptr;}}}smartPtr(const smartPtr& ptr)//左值拷贝构造{this->p = ptr.p;this->cnt = ptr.cnt;if (p) {cnt->add();}}smartPtr(smartPtr&& ptr)//右值拷贝构造{this->p = ptr.p;this->cnt = ptr.cnt;//将原资源的指针置空ptr.p = nullptr;ptr.cnt = nullptr;}smartPtr<T>& operator=(const smartPtr& ptr)//左值赋值运算符重载{//把原先的资源做处理if (this->p) {cnt->sub();if (cnt->get() == 0){delete p;}}//指向新资源this->p = ptr.p;this->cnt = ptr.cnt;this->cnt->add();return *this;}smartPtr<T>& operator=(const smartPtr&& ptr)//右值赋值运算符重载{//处理旧资源if (this->p){cnt->sub();if (cnt->get() == 0){delete p;}}//指向新资源this->p = ptr.p;this->cnt = ptr.cnt;//处理右值指针ptr.p = nullptr;ptr.cnt = nullptr;return *this;}T* get()//获取原始指针{return p;}T* operator->()//箭头{return p;}T& operator*()//解引用{return *p;}int getCount()//获取引用计数{if (!cnt) return 0;return cnt->get();}private:T* p;Count* cnt;
};int main()
{int* p = new int(123);smartPtr<int> ptr1(p);cout << ptr1.getCount() << endl;{smartPtr<int> ptr2(ptr1);cout << ptr2.getCount() << endl;}cout << ptr1.getCount() << endl;smartPtr<int> ptr3;cout << ptr3.getCount() << endl;ptr3 = ptr1;cout << ptr3.getCount() << endl;return 0;
}
赋值运算符重载的返回值是 smartPtr<T>& 原因是,这样可以方便连续赋值 类似 a = b = c 的方式。
代码不是很完善,有什么问题,欢迎大家批评指正。