boost::intrusive_ptr

トップページ > メモリ管理 >

abstract

必要なヘッダ
<boost/intrusive_ptr.hpp>
出来ること
ポインタの自動delete (侵入型参照カウント方式)
リファレンス
en / jp

sample

サンプルの動作確認バージョン [GCC4.4/1.43.0] [VC10/1.43.0]

#include <vector>
#include <iostream>
#include <boost/intrusive_ptr.hpp>
using namespace std;

namespace my
{
	class SharedObject
	{
	private:
		SharedObject() : ref_count(1) {}
	public:
		static SharedObject* create() { return new SharedObject; }
		int AddRef()  { return ++ref_count; }
		int Release() {
			if( 0 == --ref_count ) { delete this; return 0; }
			return ref_count;
		}
		void Hello()
		{
			cout << "hello." << endl;
		}
	private:
		int ref_count;
	};

	void intrusive_ptr_add_ref( SharedObject* ptr )
	{
		ptr->AddRef();
	}

	void intrusive_ptr_release( SharedObject* ptr )
	{
		ptr->Release();
	}
}

int main()
{
	typedef boost::intrusive_ptr<my::SharedObject> Ptr;

	Ptr p = Ptr(my::SharedObject::create(),false);
	vector< Ptr > v;
	  // vectorに入れたり。

	v.push_back( Ptr(my::SharedObject::create(),false) );
	v.push_back( Ptr(my::SharedObject::create(),false) );
	v.push_back( Ptr(my::SharedObject::create(),false) );
	v.push_back( p );

	p->Hello();
	  // pはさっき他にコピーしたけれど、まだここからも参照可能。

	return 0;
} // ここで全てdeleteされる。

etc

shared_ptr の場合、 new できて delete できるオブジェクトになら何にでも利用することができます。が、

など、場合によっては最適な解ではないことがあります。前者の問題は、 オブジェクト自体にカウンタ変数を含めてしまえば一回の割り当てで済むので、 まとめると、「オブジェクトの中に参照カウント計測の仕組みが備わっている場合」 には shared_ptr とは別のスマートポインタがあると便利かも、 ということになります。そこで intrusive_ptr

このクラスは、参照カウントの上げ下げの際に

の二つの関数のみを利用します。ので、自分の使うオブジェクトに応じて、 この二つを用意して適切にカウント上げ下げや削除を行えばOK。例えばCOMなら

void intrusive_ptr_add_ref(IUnknown* p) { p->AddRef(); }
void intrusive_ptr_release(IUnknown* p) { p->Release(); }

みたいに定義しておいて利用します。

see also

presented by k.inaba (kiki .a.t. kmonos.net) under CC0