intrusive_ptr源码分析
来源:互联网 发布:青岛太阳软件 编辑:程序博客网 时间:2024/06/02 17:52
intrusive_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,不需要虚函数的开销,确实性能强一些。
0 0
- intrusive_ptr源码分析
- intrusive_ptr
- intrusive_ptr
- boost智能指针之shared_ptr,scoped_ptr,intrusive_ptr,weak_ptr源码简析
- boost::intrusive_ptr原理介绍
- boost::intrusive_ptr用法
- BOOST简介-Intrusive_ptr
- boost学习之-intrusive_ptr
- 智能指针 intrusive_ptr
- C++智能指针 intrusive_ptr
- boost::intrusive_ptr用法
- boost intrusive_ptr指针
- boost::intrusive_ptr原理介绍
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- RadAsm + OD 搭配编写和调试汇编程序
- 第七章 构造函数&this&静态&单例模式
- iOS程序中的内存分配 栈区堆区全局区
- scanf()输入数字和字符
- python 4-6 如何去掉字符串中不需要的字符strip('-+*')/lstrip()/rstrip()/切片分段+/replace/sub/translate
- intrusive_ptr源码分析
- 机器学习笔记之朴素贝叶斯分类算法
- Android SVG矢量资源的使用方法
- Spring+redis的整合
- 编程珠玑: 13章 搜索 13.1生成[0 ,maxval]范围内m各随机整数的有序序列 -------解题总结
- SpringMvc+Quartz执行多次的处理
- [Shell]一个特好用的查找命令 find + grep
- 深入理解Java内存模型
- Hive分组统计前top N条记录