侵入式对象计数的设计原理相对非侵入式的来说:
具有以下优点:
1、一个资源对象无论被多少个侵入式智能指针包含,从始至终只有一个引用计数变量,不需要在每一个使用智能指针对象的地方都new一个计数对象,这样子效率比较高,使用内存也比较少,也比较安全;2、因为引用计数存储在对象本身,所以在函数调用的时候可以直接传递资源对象地址,而不用担心引用计数值丢失(非侵入式智能指针对象的拷贝,必须带着智能指针模板,否则就会出现对象引用计数丢失)。
缺点是:1、资源类必须有引用计数变量,并且该变量的增减可以被侵入式智能指针模板基类操作,这显得麻烦;2、如果该类并不想使用智能指针,它还是会带着引用计数变量。
下面上代码:
template<class T>
class intrusive_ptr
{
private:
typedef intrusive_ptr this_type;
T* p_;
public:
typedef T element_type;
typedef T value_type;
intrusive_ptr():p_(NULL){}
intrusive_ptr(T* p,bool add_ref=true)
:p_(p)
{
if(p_ != 0 && add_ref)
intrusive_ptr_add_ref(p_);
}
template<class U>
intrusive_ptr( intrusive_ptr<U> const & rhs, typename enable_if<is_convertible<U *, T *>, void ***>::type = 0)
: p_( rhs.get() )
{
if( p_ != 0 )
intrusive_ptr_add_ref( p_ );
}
intrusive_ptr(intrusive_ptr const& rhs)
:p_(rhs.p_)
{
if (p_!=0)
{
intrusive_ptr_add_ref( p_ );
}
}
~intrusive_ptr()
{
if (p_ !=0)
{
intrusive_ptr_release(p_);
}
}
void swap(intrusive_ptr& rhs)
{
T* tmp = p_;
p_ = rhs.p_;
rhs.p_ = tmp;
}
template<class U>
intrusive_ptr& operator =(intrusive_ptr<U> const& rhs)
{
this_type(rhs).swap(*this);
return *this;
}
intrusive_ptr& operator=(intrusive_ptr const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
intrusive_ptr & operator=(T * rhs)
{
this_type(rhs).swap(*this);
return *this;
}
void reset()
{
this_type().swap(*this);
}
void reset(T* rhs)
{
this_type(rhs).swap(*this);
}
T* get()const
{
return p_;
}
T& operator*() const
{
return *p_;
}
T* operator->()const
{
return p_;
}
typedef T* (this_type::*unspecified_bool_type)()const;
operator unspecified_bool_type() const // never throws
{
return p_ == 0 ? 0: &this_type::get;
}
// operator! is a Borland-specific workaround
bool operator! () const
{
return p_ == 0;
}
};
struct TestCounter : public object_counter<TestCounter, size_t, Mutex>
{
string _s;
mutable int _ref_count;
TestCounter(const char* s = "")
: _s(s)
, _ref_count(0)
{}
friend void intrusive_ptr_add_ref(const TestCounter * p)
{
++p->_ref_count;
}
friend void intrusive_ptr_release(const TestCounter * p)
{
if(--p->_ref_count <= 0)
delete p;
}
int get_ref_count()
{
return _ref_count;
}
};
int main(int argc, char ** argv)
{
{
intrusive_ptr<TestCounter> p(new TestCounter("abcde"));
intrusive_ptr<const TestCounter> p2 ( p );
//intrusive_ptr<TestCounter> p2 = shared_const_cast<TestCounter>(p);
//cout << p.use_count() << endl;
cout << "TestCounter count: " << TestCounter::get_object_count()<<" "<<p->get_ref_count() << endl;
cout << p << endl;
}
cout << "TestCounter count: " << TestCounter::get_object_count() << endl;
return 0;
}
p->get_ref_count()
输出是2
当出了作用域,就会输出0;
更多文章,欢迎访问:http://blog.csdn.net/wallwind/