intrusive_ptr源码分析
2017-01-22 18:36
197 查看
intrusive_ptr是一个侵入式的引用计数型智能指针,它可以用于以下两种情形:
对内存占用要求非常严格,要求必须与原始指针一样
现存代码已经有了引用计数机制管理的对象
boost库不推荐使用intrusive_ptr,因为shared_ptr已经非常强大且灵活,工作足够好,可以满足绝大部分的需要。
下面来看一下intrusive的源码:
呵呵,非常简单,就是这么一点。但是我们发现,intrusive_ptr的构造析构等函数中,都使用了所管理的指针,以其作为参数执行某个函数。但实际上,这些函数是没有定义的。需要我们自己定义。
因为这几个函数的源码是这样的:
呵,只有声明。
所以我们在使用intrusive_ptr是要自己提供引用计数,这就叫侵入式。我们可以在要管理的对象内部使用友元函数来实现上面那两个函数,执行计数器的加或减。但是通常我们会采用继承的方式实现,实现一个引用计数器基类,提供intrusive_ptr_add_ref()和intrusive_ptr_release()两个函数,然后继承它即可。
示例代码如下:
输出:
![](http://img.blog.csdn.net/20170122183142258?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRnJlZWVMaW51eA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
由于intrusive_ptr源码(上面已经给了)中不提供use_count()这个成员函数,所以我们也无法获得use_count值。
也许这样用你会觉得麻烦,不过实际上,boost中已经为我们实现了一个引用计数器的基类,我们使用intrusive_ptr时,继承该类就无需自己再费神了。
boost库中的引用计数基类是这样的:
唉,上面这些就是intrusive_ptr的用法,有点蛋疼。不过却是让人感觉很叼的样子。侵入式的智能指针,相比shared_ptr,不需要虚函数的开销,确实性能强一些。
对内存占用要求非常严格,要求必须与原始指针一样
现存代码已经有了引用计数机制管理的对象
boost库不推荐使用intrusive_ptr,因为shared_ptr已经非常强大且灵活,工作足够好,可以满足绝大部分的需要。
下面来看一下intrusive的源码:
template<class T> class intrusive_ptr { private: typedef intrusive_ptr this_type; public: typedef T element_type; intrusive_ptr() BOOST_NOEXCEPT : px( 0 ) { } intrusive_ptr( T * p, bool add_ref = true ): px( p ) { if( px != 0 && add_ref ) intrusive_ptr_add_ref( px ); } intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) { if( px != 0 ) intrusive_ptr_add_ref( px ); } ~intrusive_ptr() { if( px != 0 ) intrusive_ptr_release( px ); } // Move support //支持C++11移动构造,此处省略 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() BOOST_NOEXCEPT { this_type().swap( *this ); } void reset( T * rhs ) { this_type( rhs ).swap( *this ); } T * get() const BOOST_NOEXCEPT { return px; } T & operator*() const { BOOST_ASSERT( px != 0 ); return *px; } T * operator->() const { BOOST_ASSERT( px != 0 ); return px; } // implicit conversion to "bool" #include <boost/smart_ptr/detail/operator_bool.hpp> void swap(intrusive_ptr & rhs) BOOST_NOEXCEPT { T * tmp = px; px = rhs.px; rhs.px = tmp; } private: T * px; };
呵呵,非常简单,就是这么一点。但是我们发现,intrusive_ptr的构造析构等函数中,都使用了所管理的指针,以其作为参数执行某个函数。但实际上,这些函数是没有定义的。需要我们自己定义。
因为这几个函数的源码是这样的:
template< typename DerivedT, typename CounterPolicyT > void intrusive_ptr_add_ref(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; template< typename DerivedT, typename CounterPolicyT > void intrusive_ptr_release(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT;
呵,只有声明。
所以我们在使用intrusive_ptr是要自己提供引用计数,这就叫侵入式。我们可以在要管理的对象内部使用友元函数来实现上面那两个函数,执行计数器的加或减。但是通常我们会采用继承的方式实现,实现一个引用计数器基类,提供intrusive_ptr_add_ref()和intrusive_ptr_release()两个函数,然后继承它即可。
示例代码如下:
#include <iostream> #include <boost/intrusive_ptr.hpp> class reference_counter { int ref_count_; public: reference_counter() : ref_count_(0) {} virtual ~reference_counter() {} friend void intrusive_ptr_add_ref(reference_counter *p) { ++p->ref_count_; } friend void intrusive_ptr_release(reference_counter *p) { if(--p->ref_count_) delete p; } /* error int use_count() { return ref_count_; } */ protected: reference_counter& operator=(const reference_counter&) { // 无操作 return *this; } private: // 禁止复制构造函数 reference_counter(const reference_counter&); }; class some_class : public reference_counter { public: some_class() { std::cout << "some_class::some_class()\n"; } some_class(const some_class& other) { std::cout << "some_class(const some_class& other)\n"; } ~some_class() { std::cout << "some_class::~some_class()\n"; } }; int main() { std::cout << "Before start of scope\n"; { boost::intrusive_ptr<some_class> p1(new some_class()); boost::intrusive_ptr<some_class> p2(p1); //std::cout<<p2.use_count()<<std::endl; } std::cout << "After end of scope \n"; }
输出:
由于intrusive_ptr源码(上面已经给了)中不提供use_count()这个成员函数,所以我们也无法获得use_count值。
也许这样用你会觉得麻烦,不过实际上,boost中已经为我们实现了一个引用计数器的基类,我们使用intrusive_ptr时,继承该类就无需自己再费神了。
boost库中的引用计数基类是这样的:
template< typename DerivedT, typename CounterPolicyT > class intrusive_ref_counter { private: //! Reference counter type typedef typename CounterPolicyT::type counter_type; //! Reference counter mutable counter_type m_ref_counter; public: /*! * Default constructor * * \post <tt>use_count() == 0</tt> */ intrusive_ref_counter() BOOST_NOEXCEPT : m_ref_counter(0) { } /*! * Copy constructor * * \post <tt>use_count() == 0</tt> */ intrusive_ref_counter(intrusive_ref_counter const&) BOOST_NOEXCEPT : m_ref_counter(0) { } /*! * Assignment * * \post The reference counter is not modified after assignment */ intrusive_ref_counter& operator= (intrusive_ref_counter const&) BOOST_NOEXCEPT { return *this; } /*! * \return The reference counter */ unsigned int use_count() const BOOST_NOEXCEPT { return CounterPolicyT::load(m_ref_counter); } protected: /*! * Destructor */ BOOST_DEFAULTED_FUNCTION(~intrusive_ref_counter(), {}) friend void intrusive_ptr_add_ref< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; friend void intrusive_ptr_release< DerivedT, CounterPolicyT >(const intrusive_ref_counter< DerivedT, CounterPolicyT >* p) BOOST_NOEXCEPT; };
唉,上面这些就是intrusive_ptr的用法,有点蛋疼。不过却是让人感觉很叼的样子。侵入式的智能指针,相比shared_ptr,不需要虚函数的开销,确实性能强一些。
相关文章推荐
- folly源码分析(3)- ThreadLocalPtr
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- 《我的泛型编程观》之boost.scoped_ptr、scoped_array源码分析
- weak_ptr源码分析
- 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- PullToRefresh源码分析(Ⅲ)从源码分析PTRListView不足屏时上拉动画有2个的原因
- [osg]源码分析:OSG中的智能指针osg::ref_ptr
- opencv Ptr源码分析
- boost智能指针之shared_ptr,scoped_ptr,intrusive_ptr,weak_ptr源码简析
- [osg]源码分析:OSG中的智能指针osg::ref_ptr
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- C++:浅谈c++资源管理以及对[STL]智能指针auto_ptr源码分析,左值与右值
- 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- shared_ptr源码分析
- shared_ptr源码分析后续
- effective c++条款13-17 “以对象管理资源”之auto_ptr源码分析
- auto_ptr源码分析
- boost::scoped_ptr 源码分析
- [osg]源码分析:OSG中的智能指针osg::ref_ptr