weakptr的作为弱引用指针,其实现依赖于counter的计数器类和share_ptr的赋值,构造,所以先把counter和share_ptr简单实现
Counter简单实现
class Counter
{
public:
Counter() : s(0), w(0){};
int s; //share_ptr的引用计数
int w; //weak_ptr的引用计数
};
counter对象的目地就是用来申请一个块内存来存引用基数,s是share_ptr的引用计数,w是weak_ptr的引用计数,当w为0时,删除Counter对象。
share_ptr的简单实现
template <class T>
class WeakPtr; //为了用weak_ptr的lock(),来生成share_ptr用,需要拷贝构造用
template <class T>
class SharePtr
{
public:
SharePtr(T *p = 0) : _ptr(p) // 构造函数传入所管理对象的指针
{
cnt = new Counter(); // 新建Counter对象
if (p) // 对象指针不为nullptr
cnt->s = 1; // 引用计数器初值
cout << "in construct " << cnt->s << endl;
}
~SharePtr() // 析构函数
{
release(); // 释放所管理对象,如果引用计数为0则回收所管理对象对应内存空间
}
SharePtr(SharePtr<T> const &s) // 拷贝构造函数
{
cout << "in copy con" << endl;
_ptr = s._ptr; // 复制对象指针
(s.cnt)->s++; // 原share_ptr对象引用计数自增
cout << "copy construct" << (s.cnt)->s << endl;
cnt = s.cnt; // 复制Counter对象
}
SharePtr(WeakPtr<T> const &w) //为了用weak_ptr的lock(),来生成share_ptr用,需要拷贝构造用
{
cout << "in w copy con " << endl;
_ptr = w._ptr; // 复制weak_ptr管理对象的指针
(w.cnt)->s++; // 引用计数自增
cout << "copy w construct" << (w.cnt)->s << endl;
cnt = w.cnt; // 复制Count对象
}
SharePtr<T> &operator=(SharePtr<T> &s) // =运算符重载
{
if (this != &s) // 防止自我引用,导致引用计数增加
{
release(); // 先释放原管理对象的所有权
(s.cnt)->s++; // 引用计数自增
cout << "assign construct " << (s.cnt)->s << endl;
cnt = s.cnt; // 复制Count对象
_ptr = s._ptr; // 复制新管理对象的指针
}
return *this;
}
T &operator*() // 重载*运算符
{
return *_ptr;
}
T *operator->() // 重载->运算符
{
return _ptr;
}
friend class WeakPtr<T>; // 方便weak_ptr与share_ptr设置引用计数和赋值
protected:
void release() // 释放原管理对象所有权,若引用计数为0,回收所管理对象的内存
{
cnt->s--; // 引用计数减1
cout << "release " << cnt->s << endl;
if (cnt->s < 1)
{
delete _ptr;
if (cnt->w < 1)
{
delete cnt;
cnt = NULL;
}
}
}
private:
T *_ptr; // 所管理对象的指针
Counter *cnt; // 每个share_ptr都有独立的的引用计数器,同一个管理对象所对应的所有share_ptr中的计数值一致
};
share_ptr的给出的函数接口为:构造,拷贝构造,赋值,解引用,通过release来在引用计数为0的时候删除_ptr和cnt的内存。
weak_ptr简单实现
template <class T>
class WeakPtr
{
public: //给出默认构造和拷贝构造,其中拷贝构造不能有从原始指针进行构造
WeakPtr() // 默认构造
{
_ptr = 0;
cnt = new Count();
}
WeakPtr(SharePtr<T> &s) : _ptr(s._ptr), cnt(s.cnt) // 通过share_str拷贝构造
{
cout << "w con s" << endl;
cnt->w++; // 为所管理对象的weak_ptr计数
}
WeakPtr(WeakPtr<T> &w) : _ptr(w._ptr), cnt(w.cnt) // 通过weak_str拷贝构造
{
cnt->w++; // 为所管理对象的weak_ptr计数
}
~WeakPtr()
{
release();
}
WeakPtr<T> &operator=(WeakPtr<T> &w) // 通过weak_ptr赋值
{
if (this != &w) // 防止自我赋值
{
release(); // 释放原管理对象
cnt = w.cnt;
cnt->w++;
_ptr = w._ptr;
}
return *this;
}
WeakPtr<T> &operator=(SharePtr<T> &s) // 通过share_ptr赋值
{
cout << "w = s" << endl;
release();
cnt = s.cnt;
cnt->w++;
_ptr = s._ptr;
return *this;
}
SharePtr<T> lock() // lock方法将weak_ptr转换为share_ptr
{
return SharePtr<T>(*this); // 调用share_ptr的拷贝构造
}
bool expired() // 判断所管理对象是否被释放
{
if (cnt) // Count指针非空
{
if (cnt->s > 0) // 引用计数不为0,返回false
{
cout << "empty" << cnt->s << endl;
return false;
}
}
return true; // 其他返回true
}
friend class SharePtr<T>; //方便weak_ptr与share_ptr设置引用计数和赋值
protected:
void release()
{
if (cnt)
{
cnt->w--; // weak_ptr计数减1
cout << "weakptr release" << cnt->w << endl;
if (cnt->w < 1 && cnt->s < 1) // weak_ptr与share_ptr计数均为0
{
//delete cnt;
cnt = NULL;
}
}
}
private:
T *_ptr;
Counter *cnt;
};
weak_ptr一般通过share_ptr来构造,通过expired函数检查原始指针是否为空,lock来转化为share_ptr。