C++ 共享\u ptr和弱\u ptr失败的常见情况

C++ 共享\u ptr和弱\u ptr失败的常见情况,c++,shared-ptr,weak-ptr,private-inheritance,enable-shared-from-this,C++,Shared Ptr,Weak Ptr,Private Inheritance,Enable Shared From This,我在使用共享\u ptr和弱\u ptr以及从此启用共享\u时遇到问题 当我在谷歌上搜索我看到的症状时,每个人都建议“当没有共享\u ptr实例拥有你的对象时,你不能使用共享\u from\u this()” 但那不是我的情况 考虑以下代码: #include <memory> #include <cassert> class MyClass : std::enable_shared_from_this<MyClass> { public: void

我在使用
共享\u ptr
弱\u ptr
以及
从此启用共享\u时遇到问题

当我在谷歌上搜索我看到的症状时,每个人都建议“当没有
共享\u ptr
实例拥有你的对象时,你不能使用
共享\u from\u 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:std::从\u中启用\u共享\u
{
公众:
作废此_失败()
{
//甚至不断言(),因为它抛出bad\u weak\u ptr
断言(从_this()共享_);
}
无效此\u也失败了\u()
{
std::weak_ptr weak=来自_this()的弱_;
std::shared_ptr strong=weak.lock();
//此断言失败
断言(strong.get());
}
};
int main()
{
std::shared_ptr obj=std::make_shared();
obj->此_失败();
obj->此_也失败了_();
}

MyClass
中的两个方法都会使程序崩溃。我一定是缺少了一些明显的东西-它是什么?

您必须从
std::enable\u shared\u from\u this
公开继承。私下继承没有帮助-
std::shared\u ptr
无法访问基类并正确设置它。

您必须从公开继承de>std::从_this启用_shared _
以使其工作。

这一定是我见过的最违反直觉的行为之一。为什么它不会导致编译时错误?--解释如下:@LubosD我不明白为什么会出现编译器错误。从编译器的角度来看,私下继承是可以的,并调用
shAddyFROMX这个< /COD>是很好的。它不提供所需的运行时行为,不是编译器问题。代码无论它是否给了你期望的行为,都是格式良好的C++。@ LubosD没有简单的方法来编译错误。<代码> STD::SyrdypPTR< /Calpter没有构造函数来判断你是否做了一个。从
std::enable_shared_from_this
私下继承的错误,或者您是否只是从公开继承自
std::enable_shared_from_this
的某个类私下继承的错误。
shared_from_this
函数无法知道最派生的类类型,因此也无法检测程序员的错误。W嗯,标准可能会强制要求使用检查基,然后抱怨它是否不明确或不可访问。@LubosD反直觉的是,类不需要从
std::enable_shared_from_this
派生,但只有在它这样做的情况下才会发生某些事情。这非常肮脏,如果您分配另一个ses成员身份而不是继承。只需拥有自己的
弱\u ptr
并自行维护即可。