スマートポインタ
VisitorパターンをC++で組もうとして、
void AcceptorEx::accept( smart_ptr< Visitor > v ){ v->visit( smart_ptr< Acceptor >( this ) ); }
ええ、失敗しました(;´Д`)
スマートポインタにthisを渡した時点で参照カウントは1。
んでコピーしてvisitの中に入っている時点では2。
visitを抜けると1。
で、acceptを抜けると0になり、thisが解放されます(;´Д`)
でも、自分自身のスマートポインタってどうやって渡すんだろう。
こんな感じかな?
class Hoge{ public: void setThis( smart_ptr< Hoge > this_ ){ _this = this_; } smart_ptr< Hoge > getThis(){ return _this; } private: smart_ptr< Hoge > _this; };
smart_ptr< Hoge > hoge( new Hoge ); hoge->setThis( hoge );
でも、こうしてしまうと、自身が参照しているせいで、いつまで経っても解放されない。
自分の場合は、
class Hoge{ public: void setThis( smart_ptr< Hoge > this_ ){ _this = this_; //yaneSDK3rdのスマートポインタの場合 _this.getRefObj()->dec_ref(); } .... };
こんな感じで、参照カウントを1つ減らしています。
これで、外部からの参照が全て無くなったときには、自動的に解放されます。
そのときに、_thisのデストラクタで、参照カウントが-1になりますが、yane3rdSDKのスマートポインタは、0になったときにだけ解放しているので、大丈夫です。……多分(;´Д`)
ちなみに、
_this = smart_ptr< Hoge >();
こんなのは想定外デス。。
で、自分はCompositeで大体のオブジェクトを構成しているので、
class Base{ public: virtual ~Base(){} void add( smart_ptr< Base > base ){ base->setThis( base ); } }; class Composite : public Base{ public: void add( smart_ptr< Base > base ){ Base::add( base ); getList()->push_back( base ); } };
こうやって自動的にポインタがセットされるようにしておきます。
で、最初の1つ目のオブジェクトは、
smart_ptr< Base > root = smart_ptr< Base >( new Composite );
root->setThis( root );
このように、手動でsetThis()をすると。
これで何も考えずにgetThis()が出来ますヽ(´ー`)ノ
……まだ正常に動くか試してないんですけどね(;´Д`)
追記:
メモリリークは起こってないみたいなので大丈夫でしょう。