45

単純な基本クラスと派生クラスがあり、両方に必要shared_from_this()です。

この簡単な解決策:

class foo : public enable_shared_from_this<foo> {
    void foo_do_it()
    {
        cout<<"foo::do_it\n";
    }
public:
    virtual function<void()> get_callback()
    {
        return boost::bind(&foo::foo_do_it,shared_from_this());
    }
    virtual ~foo() {};
};

class bar1 : public foo , public enable_shared_from_this<bar1> {
    using enable_shared_from_this<bar1>::shared_from_this;
    void bar1_do_it()
    {
        cout<<"foo::do_it\n";
    }
public:
    virtual function<void()> get_callback()
    {
        return boost::bind(&bar1::bar1_do_it,shared_from_this());
    }
};

tr1::bad_weak_ptr次のコードで例外が発生します。

shared_ptr<foo> ptr(shared_ptr<foo>(new bar1));
function<void()> f=ptr->get_callback();
f();

したがって、「グーグル」の後、次の解決策が見つかりました。

class bar2 : public foo {
    void bar2_do_it()
    {
        cout<<"foo::do_it\n";
    }
    shared_ptr<bar2> shared_from_this()
    {
        return boost::static_pointer_cast<bar2>(foo::shared_from_this());
    }
public:
    virtual function<void()> get_callback()
    {
        return boost::bind(&bar2::bar2_do_it,shared_from_this());
    }
};

そして今、それは機能します。

enable_shared_from_this親と子の両方にとって、より便利で正しい方法はありますか?

ありがとう

4

4 に答える 4

51

基本クラスで次のように定義することで、OP ソリューションをより便利にすることができます。

protected:
    template <typename Derived>
    std::shared_ptr<Derived> shared_from_base()
    {
        return std::static_pointer_cast<Derived>(shared_from_this());
    }

これは、(再利用のために) 基本クラスに配置することで、より便利にすることができます。

#include <memory>

template <class Base>
class enable_shared_from_base
  : public std::enable_shared_from_this<Base>
{
protected:
    template <class Derived>
    std::shared_ptr<Derived> shared_from_base()
    {
        return std::static_pointer_cast<Derived>(shared_from_this());
    }
};

そして、それから次のように導き出します。

class foo : public enable_shared_from_base<foo> {
    void foo_do_it()
    {
        std::cout << "foo::do_it\n";
    }
public:
    virtual std::function<void()> get_callback()
    {
        return boost::bind(&foo::foo_do_it, shared_from_base<foo>());
    }
};

class bar1 : public foo {
    void bar1_do_it()
    {
        std::cout << "bar1::do_it\n";
    }
public:
    virtual std::function<void()> get_callback() override
    {
        return boost::bind(&bar1::bar1_do_it, shared_from_base<bar1>());
    }
};
于 2015-08-23T23:18:52.563 に答える
16

申し訳ありませんが、ありません。

問題は、shared_ptr<foo>shared_ptr<bar1>が異なるタイプであることです。内部で起こっていることすべてを理解しているわけではありませんがコンストラクターが返されて a に割り当てられるとshared_ptr<foo>、内部weak_ptr<bar1>は何も指していないことを認識し ( a だけshared_ptr<bar1>がカウンターをインクリメントするため)、それ自体をリセットします。を呼び出すbar1::shared_from_thisと、内部が何も指していないget_callbackため、例外が発生します。weak_ptr

基本的enable_shared_from_thisに、階層内の単一のクラスからのみ透過的に機能するようです。手動で実装しようとすると、問題が明らかになるはずです。

于 2009-03-21T17:30:30.320 に答える