Boost中intrusive_ptr使用案例

12 篇文章 5 订阅

1 简介Boost::intrusive_ptr

总体上讲:Boost::intrusive_ptr和shared_ptr功能上几乎是一致唯一不同的是,计数器递增、递减可以由用户自定义。

// 递增计数器,注意:函数名是内置,必须写这个名字!!!
void intrusive_ptr_add_ref(T *p)

// 递减计数器,注意:函数名是内置,必须写这个名字!!!
void intrusive_ptr_release(T *p)

下面分享下两个小案例

2 Demo1

假定,定义一个count_data,里面有一个计数器m_count。其中这个计数器就相当于shared_ptr的内置计数器,只不过intrusive_ptr可以单独操作。

  1. 简要实现intrusive_ptr_add_ref和intrusive_ptr_release
  2. counted_ptr就像shared_ptr一样智能,以至于根据m_count正确的析构对象
  3. counted_ptr weak_p(p.get(), false);,false相当于是weak_ptr(是一个观察者,不会增加引用计数),默认是shared_ptr
#include <iostream>
#include <boost/smart_ptr.hpp>

struct count_data
{
    int m_count = 0;
    // other funtion or data
};

// 下面两个函数是内置的,只需要填写计算变量++/--
void intrusive_ptr_add_ref(count_data *p) {
    ++p->m_count;
}

void intrusive_ptr_release(count_data *p) {
    if (--p->m_count == 0)
        delete p;
}

int main(int argc, char *argv[])
{
    typedef boost::intrusive_ptr<count_data> counted_ptr;

    counted_ptr p(new count_data);
    assert(p);
    assert(p->m_count == 1); // p拥有

    counted_ptr p2(p);
    assert(p->m_count == 2); // 指针拷贝构造,p和p2同时拥有

    counted_ptr weak_p(p.get(), false); // 值为false,相当于weak_ptr,只是一个观察者,不会增加引用计数
    assert(weak_p->m_count == 2);       // p和p2同时拥有,weak_p观察者

    p2.reset(); // 将p2置零
    assert(!p2);
    assert(p->m_count == 1); // p拥有,weak_p观察者
}

3 Demo 2

目的: 更加简化计数管理,直接继承intrusive_ref_counter即可
下面的代码并没有使用intrusive_ptr_add_refintrusive_ptr_release,同时也不需要计数器m_count,更加像shared_ptr了。

  1. 直接继承intrusive_ref_counter,之类可以得到计算能力
  2. 头文件 <boost/smart_ptr/intrusive_ref_counter.hpp>
#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>

// Method2
struct count_data2 : public boost::intrusive_ref_counter<count_data2>
{
    /* data */
};

int main(int argc, char *argv[])
{
       typedef boost::intrusive_ptr<count_data2> counted_ptr2;

       counted_ptr2 p(new count_data2);
       assert(p);
       assert(p->use_count() == 1); // p拥有,正确析构
}

4 内部部分API简要的实现

可以看出,

  1. intrusive_ptr在构造,析构调用intrusive_ptr_add_refintrusive_ptr_release进行计数管理
    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 );
    }
  1. reset相当于置零,其中this_type是intrusive_ptr<>,构造一个空的intrusive_ptr再和自己交换,当然也就置0了哈。
    void reset()
    {
    	// 等效于intrusive_ptr<>().swap(*this)
        this_type().swap( *this );
    }

默认构造一个空的,px是指针,pn是计数器

    BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 )
    {
    }

更加详细的代码。可以参考Boost的源码

5 有何作用?

既然intrusive_ptr和shared_ptr如此相像,那么intrusive_ptr有什么作用呢?
答:如果你的类中有了计数管理器,可以考虑intrusive_ptr,否则都用shared_ptr,因为shared_ptr不需要增加代码,灵活性很高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值