当base和派生类都继承自boost :: enable_shared_from_this时,错误的指针

Ken*_*Ken 4 c++ boost multiple-inheritance shared-ptr enable-shared-from-this

我有一个派生自boost :: enable_shared_from_this的基类,然后是另一个派生自基类和boost :: enable_shared_from_this的类:

#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

using namespace boost;

class A : public enable_shared_from_this<A> { };

class B : public A , public enable_shared_from_this<B> {
public:
    using enable_shared_from_this<B>::shared_from_this;
};

int main() {
shared_ptr<B> b = shared_ptr<B>(new B());
shared_ptr<B> b_ = b->shared_from_this();

return 0;
}
Run Code Online (Sandbox Code Playgroud)

这编译但在运行时它给出

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
  what():  tr1::bad_weak_ptr
Aborted
Run Code Online (Sandbox Code Playgroud)

造成这种情况的原因是什么,有什么办法吗?

编辑:

如果我需要这样的东西怎么办:

class A : public enable_shared_from_this<A> { };
class B : public enable_shared_from_this<B> { };    

class C : public A, public B, public enable_shared_from_this<C> {
public:
    using enable_shared_from_this<C>::shared_from_this;
};
Run Code Online (Sandbox Code Playgroud)

这样A和B都需要自己的shared_from_this(并且一个人不能从另一个继承它),而C需要A,B和shared_from_this?

Fra*_*ser 7

您不应该enable_shared_from_this在给定的继承链中多次继承.

在这种情况下,你可以离开的基类A继承enable_shared_from_this,并有派生类B回报shared_ptr<A>,然后static_pointer_castshared_ptr<B>.

或者正如Omnifarious指出的那样,你可以有一个功能,B为你做这个.虽然,而不是重载,shared_from_this()我倾向于明确命名的函数,以最大限度地减少该类客户端的意外:

#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

using boost::shared_ptr;

class A : public boost::enable_shared_from_this<A> { };

class B : public A {
public:
    using enable_shared_from_this<A>::shared_from_this;
    shared_ptr<B> shared_B_from_this() {
        return boost::static_pointer_cast<B>(shared_from_this());
    }
    shared_ptr<B const> shared_B_from_this() const {
        return boost::static_pointer_cast<B const>(shared_from_this());
    }
};

int main() {
    shared_ptr<B> b = shared_ptr<B>(new B);
    shared_ptr<B> b1 = boost::static_pointer_cast<B>(b->shared_from_this());
    shared_ptr<B> b2 = b->shared_B_from_this();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Omn*_*ous 5

以下是我将如何解决您的问题:

#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>

using namespace boost;

class virt_enable_shared_from_this :
   public enable_shared_from_this<virt_enable_shared_from_this>
{
 public:
   virtual ~virt_enable_shared_from_this() {}
};

template <class T>
class my_enable_shared_from_this : virtual public virt_enable_shared_from_this
{
 public:
   shared_ptr<T> shared_from_this() {
      return dynamic_pointer_cast<T>(virt_enable_shared_from_this::shared_from_this());
   }
};

class A : public my_enable_shared_from_this<A> { };

class B : public my_enable_shared_from_this<B> { };

class C : public A, public B, public my_enable_shared_from_this<C> {
 public:
   using my_enable_shared_from_this<C>::shared_from_this;
};

int main() {
   shared_ptr<C> c = shared_ptr<C>(new C());
   shared_ptr<C> c_ = c->shared_from_this();

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这很痛苦,至少有点难看。但它工作得相当好,在时尚之后。我认为Fraser重新思考您的设计的想法可能是更好的选择。