サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
using namespace boost;
struct test {
test(const char* name) : name_(name) {}
~test() {cout << name_ << " destructed." << endl;}
void showName() {cout << "Name: " << name_ << endl;}
const char* name_;
};
int main()
{
shared_ptr<test> sp( new test("ABC") );
weak_ptr<test> wp( sp );
// ポインタが有効なら処理を実行
if( shared_ptr<test> tmp = wp.lock() )
tmp->showName();
else
cout << "already deleted." << endl;
// ここでdeleteされる
sp.reset();
// ポインタが有効なら処理を実行
if( shared_ptr<test> tmp = wp.lock() )
tmp->showName();
else
cout << "already deleted." << endl;
return 0;
}
Name: ABC ABC destructed. already deleted.
shared_ptr
と共に使います。
shared_ptr
とこちらとの違いは、weak_ptr
は参照カウントを上げたり下げたりしないということ。
つまり、同じオブジェクトを指す weak_ptr
が生きていたとしても、
shared_ptr
が全て無くなった場合は(参照カウント0になるので)
対象オブジェクトは delete
されてしまいます。
そういう使い方をする時は、shared_ptr::get()
で普通のポインタを取っておいて使いまわせばよいではないか?
との疑問が浮かびます。が、weak_ptr
の場合、参照カウント 0
になったオブジェクトを利用しようとすると
null を返して既に無効になったことを知らせてくれたり、
処理をする際に一時的に shared_ptr
を作ることで、作業中に突然
delete
されたりする事態を防ぐことができて便利です。
「オブジェクトを所有するわけではないので shared_ptr
を使う場面ではないのだけれど、
対象オブジェクトが解放されたあともその変数で参照する可能性があるので、
そのときには解放されたことを検知したい」 という場面で使います。
Observer パターンで監視される側が通知相手を weak_ptr
で覚えておく、
というのが一番典型的な使用例です。