一个基于引用计数的智能指针类
自己刚写的,里面还混了一些调试代码,大概试了一下工作的还可以。
大家帮忙提点意见,顺便看看是否还有leak
template<typename T> class ref_obj;
template<typename T> class ref_ptr
{
public:
ref_ptr() : m_pobj(NULL) {}
ref_ptr(T *pdata);
ref_ptr(const ref_ptr<T> &rp);
~ref_ptr();
ref_ptr &operator = (const ref_ptr<T> &rp);
ref_ptr &operator = (T *pdata);
T &operator * () const;
T *operator -> () const;
private:
ref_obj<T> *m_pobj;
};
template<typename T> class ref_obj
{
public:
ref_obj(T *pdata) : m_pdata(pdata) { m_cref = 0L; }
virtual ~ref_obj() { delete m_pdata; }
T *get_data() const { return m_pdata; }
void inc_ref() const { if (m_pdata) m_cref++; std::cout << m_cref << std::endl; }
void dec_ref() const { if (m_cref) m_cref--; std::cout << m_cref << std::endl; if (!m_cref) delete this; }
private:
T *m_pdata;
mutable long m_cref;
};
template<typename T> ref_ptr<T>::ref_ptr(const ref_ptr<T> &rp)
: m_pobj(NULL) { operator = (rp); }
template<typename T> ref_ptr<T>::ref_ptr(T *pdata)
: m_pobj(new ref_obj<T>(pdata)) { m_pobj->inc_ref(); }
template<typename T> ref_ptr<T>::~ref_ptr()
{ if (m_pobj) m_pobj->dec_ref(); }
template<typename T> ref_ptr<T> &ref_ptr<T>::operator = (const ref_ptr<T> &rp)
{
if (m_pobj) m_pobj->dec_ref();
m_pobj = rp.m_pobj;
m_pobj->inc_ref();
return *this;
}
template<typename T> ref_ptr<T> &ref_ptr<T>::operator = (T *pdata)
{
if (m_pobj) m_pobj->dec_ref();
m_pobj = new ref_obj<T>(pdata);
m_pobj->inc_ref();
return *this;
}
template<typename T> T &ref_ptr<T>::operator * () const
{ return *m_pobj->get_data(); } // assert(m_pobj)
template<typename T> T *ref_ptr<T>::operator -> () const
{ return m_pobj->get_data(); }
////////////////////
测试代码:
#include <iostream>
#include <cstdlib>
#include <string>
#include "ref_ptr.h"
using namespace std;
void run();
class A
{
public:
A(const string &s) : m(s) { cout << "new A(" << m << ")" << endl; }
~A() { cout << "delete A(" << m << ")" << endl; }
const string &gets(void) const { return m; }
private:
string m;
};
int main()
{
run();
system("pause");
}
ref_ptr<A> f(ref_ptr<A> &s)
{
ref_ptr<A> sp = new A("string 1");
s = sp;
ref_ptr<A> q = new A("string 2");
sp = q;
q = sp;
return new A("string 3");
}
void run()
{
ref_ptr<A> pa;
ref_ptr<A> pb;
pb = f(pa);
cout << (*pa).gets().c_str() << endl;
cout << pb->gets().c_str() << endl;
}