概述
(1)理解share的意义,多个智能指针可以共享一份内存空间(通常是new出来的类实例)。
(2)体现在shared_ptr的use_count()计数上,每多一个智能指针指向该内存资源,计数就加1,每结束一个智能指针则计数减1。
(3)当use_count()为0时,意味着没有任何智能指针指向申请的内存空间,那么就回收此内存资源。
详细解释见代码注释
代码
#include"iostream"
#include<mutex>
using namespace std;
//辅助类
template<typename T>
class counter
{
private:
T* ptr; //指向内存资源的指针
int cnt; //计数,统计有多少SharePtr拥有此资源
mutex mx;
public:
counter(T* p) :ptr(p), cnt(1) {};
~counter()
{
delete ptr;
}
int AddCnt()
{
mx.lock();
cnt++;
mx.unlock();
return cnt;
}
int DecCnt()
{
mx.lock();
cnt--;
mx.unlock();
return cnt;
}
T* Get()
{
return ptr;
}
int Count()
{
return cnt;
}
};
//自定义智能指针
template<typename T>
class SharePtr
{
private:
counter<T>* cter; //辅助对象,所有SharePtr实例对象共享此辅助对象
public:
SharePtr(T* p = nullptr) :cter(new counter<T>(p)) {} //SharePtr指向数据的指针放在辅助对象中
SharePtr(const SharePtr<T>& rhs)
{
cter = rhs.cter;
cter->AddCnt(); //计数加一
}
~SharePtr()
{
if (cter->DecCnt() == 0) //计数-1
delete cter;
//计数为0,说明当前SharePtr就是最后一个拥有cter资源的SharePtr
//当前SharePtr生命周期结束后,cter资源已经没有任何SharePtr可以指向了,没人管自然就应该回收资源
}
SharePtr& operator=(const SharePtr<T>& rhs)
{
if (this == &rhs)
return *this;
//释放之前的资源
if (cter->DecCnt() == 0) //计数-1
delete cter;
cter = rhs.cter; //获得新辅助对象
cter->AddCnt(); //计数加一
}
//重载->
T* operator->()
{
return cter->Get();
}
//重载*,解引用
T& operator*()
{
return *cter->Get();
}
//返回计数个数
int use_count()
{
return cter->Count();
}
};
//测试类
class Test {
public:
Test(int n = 0) :num(n) {
std::cout << "Test class construct,num = " << num << std::endl;
}
~Test() {
std::cout << "num=" << num << "资源回收" << std::endl;
}
int num;
};
int main()
{
SharePtr<Test> sp1(new Test(1));
SharePtr<Test> sp2(new Test(2));
cout << "sp1.cnt = " << sp1.use_count() << endl;
cout << "sp2.cnt = " << sp2.use_count() << endl;
cout << "-----------------------------------" << endl;
cout << "after SharePtr<Test> sp3(sp2);" << endl;
SharePtr<Test> sp3(sp2); //sp2,sp3计数都变成2
cout << "sp1.cnt = " << sp1.use_count() << endl;
cout << "sp2.cnt = " << sp2.use_count() << endl;
cout << "sp3.cnt = " << sp3.use_count() << endl;
cout << "-----------------------------------" << endl;
cout << "after sp1 = sp2" << endl;
sp1 = sp2; //sp1对应资源会释放,sp2对应计数会加1
cout << "sp1.cnt = " << sp1.use_count() << endl;
cout << "sp2.cnt = " << sp2.use_count() << endl;
cout << "sp3.cnt = " << sp3.use_count() << endl;
cout << "-----------------------------------" << endl;
cout << "main end" << endl;
}
测试结果: