gpt4 book ai didi

c++ - 从基类派生调用 shared_from_this() 给出 std::bad_weak_ptr

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:22:37 29 4
gpt4 key购买 nike

我有一个基类和一个派生类。 API 仅公开 Derived,而实现隐藏在 Base 中(gcc 属性 visibility 设置为 hidden ),因为一些内部 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);
}
};

现在是什么doSomething做法如下:

void Base::doSomething(DerivedPtr aDerived)
{
DerivedPtr lDerived = reinterpret_cast<Derived*>(this)->shared_from_this();
}

问题如下:

  • 当我使用如上所示的简单示例时 - 它工作正常;
  • 当我在我的大项目中使用它时 - 它会抛出 std::tr1::bad_weak_ptr异常;

我正在使用 gcc-4.4.7,从回溯中我可以看到它被称为:

  1. std::tr1::enable_shared_from_this<Derived>::shared_from_this
  2. std::tr1::shared_ptr<Derived>::shared_ptr<Derived> (this=0x7fffffffd370, __r=std::tr1::weak_ptr (empty) 0x2)
  3. std::tr1::__shared_ptr<Derived, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<Derived>
  4. std::tr1::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count

__shared_count它抛出,因为:

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 }

我的 __r._M_pi 等于 0。

我知道使用 Derived 可能是个糟糕的主意在 Base ,不过这不是题材的问题,就这样吧。 (没有人可以直接实例化 Base)。

重要的是客户端(使用 API 的人)正在使用 shared_ptr,这就是 Derived 继承 enable_shared_from_this 的原因.

我想做的是了解正在发生的事情以及为什么 bad_weak_ptr异常被抛出,我能做些什么来避免它(可能是架构上的一些小变化)。


编辑

我改变了Base::doSomething根据:https://stackoverflow.com/a/9377075/1498245

现在看起来像:

void Base::doSomething(DerivedPtr aDerived)
{
DerivedPtr lDerived = std::tr1::static_pointer_cast<Derived>( static_cast<Derived*>(this)->shared_from_this() );
}

可能开始起作用了。可能吧,因为再也没有异常(exception)了,但我不太确定下面发生了什么。看起来像在 reinterpret_cast 期间有一些数据丢失。在我的真实案例中 Base类(class)要大得多,有很多成员,等等。也许就是这样。谁能对这个案子有所了解? “幕后”发生了什么?

最佳答案

Problem is as follows:

•when I use a simple example as showed above - it works fine;

•when I use it in my big project - it throws std::tr1::bad_weak_ptr exception;

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

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

我的第一个猜测是这段代码:

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

您确定仅从派生实例调用 Base::doSomething 吗?这是从层次结构的基础到派生的不安全转换。

我的第二个猜测是你正在为不是指针的东西调用 shared_from_this。我正在谈论的场景示例:

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

关于c++ - 从基类派生调用 shared_from_this() 给出 std::bad_weak_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23734388/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com