スマートポインタ

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()が出来ますヽ(´ー`)ノ


……まだ正常に動くか試してないんですけどね(;´Д`)


追記:
メモリリークは起こってないみたいなので大丈夫でしょう。