您的位置:首页 > 其它

boost.shared_ptr源码整理和使用说明

2007-08-24 22:51 363 查看

Source

#pragma once

//shared_ptr的简单实现版本
//基于引用记数的智能指针
//它可以和stl容器完美的配合
namespace kimi_boost
{

template<class T>
class shared_ptr
{
public:
typedef T element_type;
typedef T value_type;
typedef T * pointer;
typedef T& reference;
typedef unsigned long size_type;

explicit shared_ptr(T* p=0) : px(p)
{
try { pn = new size_type(1); }
catch (...) { delete(p); throw; }
}
shared_ptr& operator= (T* p)
{
if(this->px == p) return *this;
dispose();
try { pn = new size_type(1); }
catch (...) { delete(p); throw; }
px=p;
return *this;
}

shared_ptr(const shared_ptr& r) throw(): px(r.px)
{
++*r.pn;
pn = r.pn;
}
shared_ptr& operator= (const shared_ptr& r) throw()
{
if(this == &r) return *this;
dispose();
px = r.px;
++*r.pn;
pn = r.pn;
return *this;
}

template<typename Y> friend class shared_ptr;
//为了让有继续关系的shared_ptr类型赋值或构造
template<typename Y>
shared_ptr(const shared_ptr<Y>& r)
{
px = r.px;
++*r.pn;
pn = r.pn; // shared_count::op= doesn't throw
}
template<typename Y>
shared_ptr& operator= (const shared_ptr<Y>& r)
{
dispose();
px = r.px;
++*r.pn;
pn = r.pn; // shared_count::op= doesn't throw
return *this;
}

template<typename Y>
shared_ptr(Y* py)
{
try { pn = new size_type(1); }
catch (...) { delete(py); throw; }
px=py;
}
template<typename Y>
shared_ptr& operator= (Y* py)
{
if(this->px == py) return *this;
dispose();
try { pn = new size_type(1); }
catch (...) { delete(py); throw; }
px=py;
return *this;
}

~shared_ptr() { dispose(); }

void reset(T* p=0)
{
if ( px == p ) return;
if (--*pn == 0)
{ delete(px); }
else
{ // allocate new reference
// counter
// fix: prevent leak if new throws
try { pn = new size_type; }
catch (...) {
// undo effect of —*pn above to
// meet effects guarantee
++*pn;
delete(p);
throw;
} // catch
} // allocate new reference counter
*pn = 1;
px = p;
} // reset

reference operator*() const throw(){ return *px; }
pointer operator->() const throw(){ return px; }
pointer get() const throw(){ return px; }
size_type use_count() const throw()//
{ return *pn; }
bool unique() const throw()//
{ return *pn == 1; }

private:
void dispose() throw()
{
if (--*pn == 0)
{ delete px; delete pn; }
}

T * px; // contained pointer
size_type* pn; // reference counter

}; // shared_ptr

template<typename A,typename B>
inline bool operator==(shared_ptr<A> const & l, shared_ptr<B> const & r)
{
return l.get() == r.get();
}

template<typename A,typename B>
inline bool operator!=(shared_ptr<A> const & l, shared_ptr<B> const & r)
{
return l.get() != r.get();
}

}//namespace kimi_boost

Test code

class A
{
public:
A(int _a=0):a(_a){}
~A(){}
protected:
int a;
};

class B : public A
{
public:
B(int _a=0):A(_a){}
~B(){}
};

void kimi_shared_ptr_test()
{
using namespace std;
using kimi_boost::shared_ptr;

shared_ptr<int> sp;
shared_ptr<int> sp2(new int(2));
shared_ptr<int> sp3(sp2);
shared_ptr<int> sp4;
shared_ptr<int> sp5;
sp=sp2;
sp4=new int(3);
sp.reset(new int(10000));

vector< shared_ptr<int> > vsp;
vsp.push_back(sp);
vsp.push_back(sp2);
vsp.push_back(sp3);
vsp.push_back(sp4);
vsp.push_back(sp5);

shared_ptr<A> spa(new A(2));
shared_ptr<B> spb(new B(3));
spa = spb;
shared_ptr<A> spa2(new B(2345));

cout<<(sp2==sp3)<<endl;
cout<<(spa==spb)<<endl;
}

Output

1
1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: