boost::shared_ptr

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

abstract

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

sample

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

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

int main()
{
	typedef boost::shared_ptr<string> StrPtr;

	StrPtr s = StrPtr(new string("pen"));
	vector< StrPtr > v;
	  // vectorに入れたり。

	v.push_back( StrPtr(new string("this")) );
	v.push_back( StrPtr(new string("is")) );
	v.push_back( StrPtr(new string("a")) );
	v.push_back( s );

	cout << *s << endl; // sをpush_backで他にコピーしたからと言って使えなくなったりしない

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

etc

使わなくなったオブジェクトを自動で delete してくれる、スマートポインタです。 同じオブジェクトを指している shared_ptr 変数の個数が裏で自動的にカウントされて、 ゼロになると、つまりどの変数からもオブジェクトが参照されなくなると、 その瞬間に delete が呼ばれます。 この参照回数カウント機能が、 scoped_ptr や標準の std::auto_ptr との違い。複数のオブジェクトから同時に参照されるような共有オブジェクトの delete も上手くやってくれます。

と言ったところでしょうか。 また、vector 等のコンテナはオブジェクトの移動ではなくコピーを前提としているため auto_ptr を入れられないという欠点がありましたが、shared_ptr は大丈夫というのも利点。C++98 の標準ライブラリにはいってないのが疑問なくらい汎用性アリです。 auto_ptr は使わず全て shared_ptr で置き換えてもいいのではないかと個人的には思います。 scoped_ptr も無しで全部 shared_ptr で統一しちゃう派の人もいるようです。

ただし、一般的なガベージコレクションと違って、 shared_ptr で循環参照が発生すると正しく delete できなくなってしまいますので、 そこだけ注意が必要です。あまりなんでもかんでも shared_ptr にしすぎないこと。 スマートポインタは、「オブジェクトが、 自分が"所有"しているオブジェクトを指すための変数」にだけ使用します。 所有関係ではないただの参照関係のための変数は、普通のポインタです (weak_ptr の方が適切なこともたまにあります)。 たいていの場合は…特にオブジェクト指向的に設計をしている場合は、 変数が所有関係を表しているかそうでないかは比較的明らかなはず。 それをそのままコードに落とせばOKです。

どのオブジェクトがどのオブジェクトを所有していると言えるのか定かでないようなコードの場合は、 闇雲に shared_ptr にするよりは、 根本的に設計を見直すか、おそらく BoehmGC などの GC を使うべきでしょう。

see also

Cryolite 氏による以下の記事は必読です!

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