intrusive_ptr
intrusive_ptr是一種引用計數型智能指針,與之前介紹的scoped_ptr、shared_ptr不同,需要額外增加一些的代碼才能使用。
如果現存代碼已經有了引用計數機制管理的對象,那麼intrusive_ptr是一個非常好的選擇,可以包裝已有對象從而得到與shared_ptr類似的智能指針。
因爲他是引用計數類型指針,所以接口與shared_ptr很像,也可以支持static_pointer_cast()、dynamic_pointer_cast()等轉型操作,但它自己不直接管理引用計數,而是調用下面兩個函數間接管理。
//增加引用計數
void intrusive_ptr_add_ref(T *p);
//減少引用計數
void intrusive_ptr_release(T *p);
intrusive_ptr的構造函數和reset()還多出一個add_ref參數,表示是否增加引用計數,如果add_ref == true,那麼它就相當於weak_ptr,只是簡單地觀察對象。
用法:
#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace boost;
//自己定義實現引用計數的類
struct counted_data
{
//引用計數
int m_count = 0;
};
int main()
{
typedef intrusive_ptr<counted_data> counted_ptr;
//創建智能指針
counted_ptr p(new counted_data);
assert(p);
//使用operator->操作符
assert(p->m_count == 1);
//指針拷貝構造
counted_ptr p2(p);
//引用計數增加
assert(p->m_count == 2);
//弱引用
counted_ptr weak_p(p.get(), false);
//引用計數不增加
assert(weak_p->m_count == 2);
//復位指針
p2.reset();
//p2不持有指針
assert(!p2);
//引用計數減少
assert(p->m_count == 1);
getchar();
return 0;
}
注意:下面這兩個函數的實現需要放在所在的名字空間或者boost名字空間。
void intrusive_ptr_add_ref(counted_data *p)
{
++p->m_count;
}
void intrusive_ptr_release(counted_data *p)
{
if (--p->m_count == 0)
{
delete p;
}
}
引用計數器
爲了簡化實現引用計數的工作,intrusive_ptr定義了一個輔助類intrusive_ref_counter,聲明如下:
用法:
#include <iostream>
#include <boost/smart_ptr.hpp>
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
using namespace boost;
//自己定義實現引用計數的類
struct counted_data : public intrusive_ref_counter<counted_data>
{
//引用計數
int m_count = 0;
};
int main()
{
typedef intrusive_ptr<counted_data> counted_ptr;
//創建智能指針
counted_ptr p(new counted_data);
assert(p);
//使用operator->操作符
assert(p->m_count == 1);
getchar();
return 0;
}