C++ 从基类中派生的_this()调用shared_会得到std::bad_-weak_-ptr

C++ 从基类中派生的_this()调用shared_会得到std::bad_-weak_-ptr,c++,inheritance,shared-ptr,tr1,C++,Inheritance,Shared Ptr,Tr1,我有一个基类和一个派生类。API只公开派生的,而实现隐藏在Base中(gcc属性可见性设置为隐藏),因为一些内部API模块必须调用Base方法。 这样我们得到: // Base.h class Derived; class Base { typedef std::tr1::shared_ptr<Derived> DerivedPtr; public: void doSomething(DerivedPtr aDerived); protected: Base(

我有一个基类和一个派生类。API只公开派生的,而实现隐藏在Base中(gcc属性
可见性
设置为
隐藏
),因为一些内部API模块必须调用Base方法。 这样我们得到:

// Base.h
class Derived;
class Base
{
    typedef std::tr1::shared_ptr<Derived> DerivedPtr;
public:
    void doSomething(DerivedPtr aDerived);
protected:
    Base();
};


// Derived.h
class Derived : public std::tr1::enable_shared_from_this<Derived>, public Base
{
public:
    Derived():std::tr1::enable_shared_from_this<Derived>(), Base(){}
    void doSomething(DerivedPtr aDerived)
    {
        Base::doSomething(aDerived);
    }
};
问题如下:

void Base::doSomething(DerivedPtr aDerived)
{
    DerivedPtr lDerived = reinterpret_cast<Derived*>(this)->shared_from_this();
}
  • 当我使用上面显示的一个简单示例时,它工作得很好
  • 当我在我的大项目中使用它时,它抛出
    std::tr1::bad\u-weak\u-ptr
    异常
我使用的是gcc-4.4.7,从回溯中可以看到,它被称为:

  • std::tr1::启用来自此的共享\u::来自此的共享\u
  • std::tr1::shared_ptr::shared_ptr(this=0x7fffffffd370,_r=std::tr1::弱_ptr(空)0x2)
  • std::tr1::uuu shared\u ptr::uu shared\u ptr
  • std::tr1::_共享_计数::_共享_计数
  • \u共享\u计数中,它抛出,因为:

    292   template<_Lock_policy _Lp>
    293     inline
    294     __shared_count<_Lp>::
    295     __shared_count(const __weak_count<_Lp>& __r)
    296     : _M_pi(__r._M_pi)
    297     {
    298       if (_M_pi != 0)
    299     _M_pi->_M_add_ref_lock();
    300       else
    301     __throw_bad_weak_ptr();
    302     }
    
    它可能开始起作用了。可能吧,因为已经没有例外了,但我不太确定下面发生了什么。看起来在重新解释过程中有一些数据丢失。在我的现实世界中,
    Base
    类要大得多,有很多成员,等等。可能就是这样。有人能解释一下这个案子吗?“引擎盖下”发生了什么

    问题如下:

    void Base::doSomething(DerivedPtr aDerived)
    {
        DerivedPtr lDerived = reinterpret_cast<Derived*>(this)->shared_from_this();
    }
    
    •当我使用如上所示的简单示例时,效果良好

    •当我在我的大项目中使用它时,它抛出std::tr1::bad\u-weak\u-ptr异常

    这听起来像是未定义的行为

    我想到了两种可能性(因为您没有发布测试代码和项目之间的差异,我在这里猜测):

    我的第一个猜测是以下代码:

    DerivedPtr lDerived = reinterpret_cast<Derived*>(this)->shared_from_this();
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    您好,我确信Base::doSomething只从派生实例调用。并在共享的ptr上调用。请看我的编辑。
    struct Foo : public std::enable_shared_from_this<Foo> {
        std::shared_ptr<Foo> share() { return shared_from_this(); }
    };
    
    std::shared_ptr<Foo> pf(new Foo);
    auto pf2 = pf->share();  // OK, pf2 will share ownership with pf
    
    Foo localInstance;
    auto pf2 = localInstance.share();  // NOT OK, pf2 will attempt to delete a local
                                       // value at scope end