#include <iostream>
#include <memory>
#include <set>
using namespace std;
class Stu//测试类
{
private:
string name;
int age;
public:
Stu(string name, int age)
{
this->name = name;
this->age = age;
cout << "Stu的构造" << endl;
}
Stu(const Stu& stud){
cout<<"copy"<<endl;
}
void showInfo()
{
cout << "姓名:" << this->name << ",年龄:" << this->age << endl;
}
~Stu()
{
cout << "Stu的析构" << endl;
}
bool operator<(const Stu& other) const {
if (name == other.name) {
return age < other.age;
}
return name < other.name;
}
};
// 计数器类
template <class T>
class RefCount{
T * ptr; //用来指向堆区Stu对象
int count; //用来计数
public:
//构造函数
RefCount(T* ptr = nullptr)
{
this->ptr = ptr;
if(this->ptr != nullptr)
{
this->count = 1;
}
else{
this->count = 0;
}
}
//增加引用计数
void addRef()
{
this->count++;
}
//减少引用计数
int delRef()
{
//这里把计数器返回出去的目的是,
//当减完后,可直接判断计数器,如果为0,就直接释放空间
//省了一步get_count
return --this->count;
}
//获取引用计数
int get_count()
{
return this->count;
}
};
template<class T>
class SHARED_ptr{
T * ptr; //用来指向堆区Stu对象
RefCount<T> * refcount; //类中嵌套 类的指针, 用来指向计数器类
public:
//SHARED_ptr的构造
SHARED_ptr(T * ptr = nullptr)
{
this->ptr = ptr;
if(this->ptr != nullptr)
{
this->refcount = new RefCount<T>(this->ptr);
}
else{
this->refcount = new RefCount<T>();
}
}
//SHARED_ptr的析构
~SHARED_ptr()
{
//每个对象析构的时候,都让计数器--,并判断计数器是否为0,
//如果计数器为0了,说明析构的是最后一个对象,那么就释放空间
if(this->refcount->delRef() == 0){
delete ptr;
delete refcount;
this->ptr = nullptr;
this->refcount = nullptr;
}
}
//SHARED_ptr的拷贝构造
SHARED_ptr(const SHARED_ptr& other)
{
//如果外类不为空
if(other.ptr != nullptr)
{
//将外类堆地址赋值给本类的指针
this->ptr = other.ptr;
//错误理解:将外类的计数器,赋值给本类计数器<<--这种理解是错误的
//正确理解:将本类的计数器指针,也指向外类计数器的地址
this->refcount = other.refcount;
//拷贝构造调用时机是在初始化类对象时,所以本类计数器+1
this->refcount->addRef();
}
//如果外类为空
else {
this->ptr = other.ptr; //将外类堆地址赋值给本类的指针
this->refcount = other.refcount; //将外类的计数器,赋值给本类计数器
}
}
//SHARED_ptr的=号运算符重载
SHARED_ptr& operator = (const SHARED_ptr& other)
{
if(this == &other)
{
return *this;
}
//外类为空
if(other.ptr == nullptr)
{
//外类空,本类非空
if(this->ptr != nullptr)
{
//本类计数器-1,如果减后计数器为0,
//说明堆空间没人用了,该回收了
if(this->refcount->delRef() == 0)
{
delete this->ptr;
delete this->refcount;
this->ptr = nullptr;
this->refcount = nullptr;
}
}
//外类赋值给本类
this->ptr = other.ptr;
this->refcount = other.refcount;
}
//外类非空
else {
//外类非空,本类非空
if(this->ptr != nullptr)
{
//两个类都非空,先对本类进行计数器-1,
//如果计数器为0了,那就释放堆区资源
if(this->refcount->delRef() == 0)
{
delete this->ptr;
delete this->refcount;
this->ptr = nullptr;
this->refcount = nullptr;
}
}
//然后外类对本类赋值
this->ptr = other.ptr;
this->refcount = other.refcount;
//赋值后,本类计数器需要+1
this->refcount->addRef();
}
return *this;
}
T& operator*()
{
return *ptr;
}
//get方法
T* get()
{
return ptr;
}
//指针运算符重载
T* operator->()
{
return ptr;
}
//获取引用记数
int use_count()
{
return refcount->get_count();
}
};
C++智能指针shared_ptr的简单实现
于 2024-03-07 20:05:55 首次发布