`
zhangyafei_kimi
  • 浏览: 261657 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

阅读更多

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics