前面已经讲了什么是智能指针,但是还不是很好用,需要不断的进行改进,可以融合前面提到的引用计数和写时拷贝
,为智能指针增加新的功能。
1.智能指针的实现及添加模板
我们在前面自己做一个智能指针,让其帮助我们管理资源。但是这并不通用,只针对CStudent对象指针,因此,我们可以为其添加上模板的技术,这样让其更加通用。
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
//智能指针
//1.用起来像指针
//2.会自己对资源进行释放
class CStudent
{
public:
CStudent()
{
}
void test()
{
cout << "CStudent" << endl;
}
private:
char* m_pszBuf;
int m_nSex;
};
template<typename T>
class CSmartPtr;
//添加模板
template<typename T>
//引用计数器
class CRefCount
{
friend class CSmartPtr<T>;
CRefCount(T* pStu)
{
m_pObj = pStu;
m_nCount = 1;
}
~CRefCount()
{
delete m_pObj;
m_pObj = NULL;
}
//增加引用时加1
void AddRef()
{
m_nCount++;
}
//引用为0时释放
void Release()
{
if (--m_nCount == 0)
{
//这么写就表示自己一定是个堆对象
delete this;
}
}
private:
T* m_pObj;
int m_nCount;
};
//智能指针
//致命问题,CSmartPtr表达的类型是固定的,是CStudent,需要添加模板
template<typename T>
class CSmartPtr
{
public:
CSmartPtr()
{
m_pRef = NULL;
}
CSmartPtr(T* pStu)
{
m_pRef = new CRefCount <T>(pStu);
}
~CSmartPtr()
{
m_pRef->Release();
}
CSmartPtr(CSmartPtr& obj)
{
m_pRef = obj.m_pRef;
m_pRef->AddRef();
}
CSmartPtr& operator=(CSmartPtr& obj)
{
if (m_pRef == obj.m_pRef)
{
return *this;
}
if (m_pRef != NULL)
{
m_pRef->Release();
}
m_pRef = obj.m_pRef;
m_pRef->AddRef();
return *this;
}
void test2()
{
cout << "test2" << endl;
}
T* operator->()
{
return m_pRef->m_pObj;
}
T** operator&()
{
return &m_pRef->m_pObj;
}
T& operator*()
{
return *m_pRef->m_pObj;
}
operator T*()
{
return m_pRef->m_pObj;
}
// operator CStudent()
// {
// return *m_pStu;
// }
private:
//只能new出来
CRefCount<T>* m_pRef;
};
class CTest
{
public:
CTest() {}
};
int main(int argc, char* argv[])
{
CStudent* pStu = new CStudent();
CSmartPtr <CStudent> sp1(pStu);
CSmartPtr <CStudent> sp2(new CStudent()); //拷贝构造
sp2 = sp1; //运算符重载
//测试可以使用于CTest指针
CSmartPtr<CTest>sp3(new CTest);
return 0;
}
上述代码sp1和sp2的具体构造析构过程如下图所示:
有需要下载该思维导图的可以从以下链接下载:C++新特性18-智能指针的简易实现及添加模板思维导图
2.学习视频地址:智能指针的简易实现及添加模板
3.学习笔记:智能指针的简易实现及添加模板笔记