shared_ptr智能指針與auto_ptr智能指針不同的是,拷貝構造或賦值後,原來的指針仍然能夠使用。
原因是這種指針用一個引用計數來計算有多少個指針指向同一個空間,拷貝構造和賦值,都會讓計數+1,智能指針析構的時候計數-1,計數爲0才釋放內存。所以根據這幾點可以自己實現shared_ptr智能指針的功能。
#include <iostream>
using namespace std;
template<typename T>
class mshared_ptr{
T* ptr;
/* int count;//不能用普通變量來保存計數,因爲const對象無法修改
成員變量*/
int *count;//辦法是用指針
public:
//構造
mshared_ptr(T *_ptr=NULL):ptr(_ptr)
{
count=new int(0);
if(ptr!=NULL)
*count=1;
}
//拷貝構造
mshared_ptr(const mshared_ptr &r)
{
cout<<"拷貝構造"<<endl;
ptr=r.ptr;//讓兩個指針指向同一個地方
count=r.count;//讓count指針和原來的指向同一個地方
++*r.count;//原來的對象的引用計數++
}
//賦值運算符重載
mshared_ptr &operator=(const mshared_ptr &r)
{
if(--*count==0)
{
delete ptr;
delete count;
cout<<"賦值重載中釋放內存"<<endl;
}
ptr=r.ptr;
count=r.count;
++*r.count;
return *this;
}
//解引用
T operator*()
{
return *ptr;
}
//析構
~mshared_ptr()
{
if(--*count==0)
{
delete ptr;
delete count;
cout<<"析構中釋放內存"<<endl;
}
}
//引用計數
int use_count()
{
return *count;
}
};
int main(void)
{
mshared_ptr<double> ptr(new double(3.14));
cout<<*ptr<<endl;
// {
mshared_ptr<double> ptr1=ptr;
cout<<*ptr<<endl;
cout<<*ptr1<<endl;
cout<<"引用計數是"<<ptr.use_count()<<
"\t"<<ptr1.use_count()<<endl;
// }
// cout<<"ptr1刪除後ptr引用計數是"<<ptr.use_count()<<endl;
mshared_ptr<double> ptr_n1(new double(1.59));
ptr_n1=ptr;/*在讓ptr_n1指向新的空間之前,ptr_n1原來的空間的
引用計數要-1,如果爲0要清除*/
cout<<"賦值給ptr_n1後引用計數是"<<ptr.use_count()<<endl;
}