【问题标题】:Trivial cases of shared_ptr and weak_ptr failingshared_ptr 和 weak_ptr 失败的小例子
【发布时间】:2019-11-25 14:30:21
【问题描述】:

我在使用 shared_ptrweak_ptr 以及 enable_shared_from_this 时遇到问题。

当我用谷歌搜索我所看到的症状时,每个人都建议“当没有 shared_ptr 实例拥有你的对象时,你不能使用 shared_from_this()

但这不是我的情况。

考虑这段代码:

#include <memory>
#include <cassert>

class MyClass : std::enable_shared_from_this<MyClass>
{
public:
    void this_fails()
    {
        // Doesn't even assert(), because it throws bad_weak_ptr
        assert(shared_from_this());
    }
    void this_fails_too()
    {
        std::weak_ptr<MyClass> weak = weak_from_this();
        std::shared_ptr<MyClass> strong = weak.lock();
        // This assert fails
        assert(strong.get());
    }
};

int main()
{
    std::shared_ptr<MyClass> obj = std::make_shared<MyClass>();

    obj->this_fails();
    obj->this_fails_too();
}

MyClass 中的两种方法都会导致程序崩溃。我一定遗漏了一些明显的东西 - 它是什么?

【问题讨论】:

    标签: c++ shared-ptr weak-ptr private-inheritance enable-shared-from-this


    【解决方案1】:

    您必须公开std::enable_shared_from_this 继承。私下继承没有帮助 - std::shared_ptr 无法访问基类并正确设置它。

    【讨论】:

    • 这一定是我见过的最反直觉的行为之一。为什么它不会导致编译时错误? -- 解释在这里:stackoverflow.com/questions/39937112/…
    • @LubosD 我不明白您为什么会期望编译器错误。从编译器的角度来看,私有继承很好,调用shared_from_this 很好。它没有提供所需的运行时行为不是编译器的问题。代码是格式良好的 C++,无论它是否为您提供预期的行为。
    • @LubosD 没有简单的方法可以给出编译错误。 std::shared_ptr 构造函数没有机制来判断您是从std::enable_shared_from_this 私下继承还是从std::enable_shared_from_this 公开继承的某个类私下继承了错误。 shared_from_this 函数无法知道最衍生的类类型,因此它也无法检测到程序员的错误。
    • 好吧,标准可以强制使用 std::is_base_of 检查 base,然后抱怨它是否模棱两可或无法访问。
    • @LubosD 与直觉相反的是,一个类不需要从std::enable_shared_from_this 派生,但只有当它派生时才会发生某些事情。这很脏,如果您分配另一个使用成员资格而不是继承的类,这将不起作用。只需拥有自己的weak_ptr 并自己维护即可。
    【解决方案2】:

    您必须公开继承 std::enable_shared_from_this 才能使其工作。

    【讨论】:

      猜你喜欢
      • 2011-06-26
      • 2017-05-20
      • 2021-06-20
      • 1970-01-01
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      • 2012-06-02
      相关资源
      最近更新 更多