一、 shared_ptr的模擬實現
我在之前的博客《智能指針》中有說過shared_ptr的原理,那麼這篇博客,我們模擬實現一個shared_ptr,讓大家能更好的理解它的原理。
include<mutex> //這個頭文件是用來使用互斥鎖
template<class T>
class Shared_ptr
{
public:
//構造函數
Shared_ptr(T* _ptr = nullptr)
:ptr(_ptr)
, pcount(new int(1))
, pmutex(new mutex)
{}
//該函數是爲了對引用計數減1
void Release()
{
bool flag = false;
//因爲引用計數是一個臨界資源,所以當有多個線程使用它時,可能會出現問題,
//所以用互斥鎖來保證數據的安全
pmutex->lock(); //加鎖
if (--(*pcount) == 0) //如果此時引用計數爲0,說明應該要銷燬
{
delete ptr;
delete pcount;
//delete pmutex; 因爲此時我們還要使用互斥鎖,所以還不能銷燬,所以設置一個標誌位
flag = true;
}
pmutex->unlock(); //解鎖
if (flag == true)
delete pmutex;
}
//只用來對引用計數加1
void AddCount()
{
pmutex->lock(); //加鎖
(*pcount)++;
pmutex->unlock(); //解鎖
}
~Shared_ptr()
{
Release();
}
//拷貝構造
Shared_ptr(Shared_ptr<T>& sp)
:ptr(sp.ptr)
,pcount(sp.pcount)
,pmutex(sp.pmutex)
{
AddCount();
}
//賦值運算符重載
SharedPtr<T>& operator=(const SharedPtr<T>& sp)
{
if (ptr != sp.ptr)
{
// 釋放管理的舊資源
Release();
// 共享管理新對象的資源,並增加引用計數
ptr = sp.ptr;
pcount = sp.pcount;
pmutex = sp.pmutex;
AddRefCount();
}
return *this;
}
private:
T* ptr; //指向被管理的資源
//引用計數雖然是存在於每一個對象中,但是實際上它是跟隨着對象所管理的資源
//的,因此要把它設置爲指針,這樣每個對象可以通過這個指針來共享同一塊空間。
//都可以對這個引用計數進行操作
int* pcount; //引用計數
mutex* pmutex; //互斥鎖
};