shared_ptr-为什么会中断?

tno*_*rgd 1 c++ shared-ptr

在开发树状数据结构时,我写了这样的内容:

    #include <memory>

    class Node: public std::enable_shared_from_this<Node> {
    public:

        void set_root(Node & n);
    private:
        std::shared_ptr<Node> root;
        std::shared_ptr<Node> leaf;
    };

    void Node::set_root(Node & n) {
        root = n.shared_from_this();
        n.leaf = shared_from_this();
    }

    int main() {
        Node n1, n2;
        n1.set_root(n2);
    }
Run Code Online (Sandbox Code Playgroud)

代码使用clang编译,但会中断运行时间(“ libc ++ abi.dylib:以类型为std :: ____ :: bad_weak_ptr:bad_weak_ptr的未捕获异常终止)”为什么?

编辑 因此,基于答案,我想出了一个似乎可行的版本:

    #include <memory>

    class Node;
    typedef std::shared_ptr<Node> Node_SP;

    class Node: public std::enable_shared_from_this<Node> {
    public:

        void set_root(Node & n);
    private:
        std::shared_ptr<Node> root;
        std::shared_ptr<Node> leaf;
    };

    void Node::set_root(Node & n) {
        root = n.shared_from_this();
        n.leaf = shared_from_this();
    }

    int main() {
        Node_SP n1 = std::shared_ptr<Node>(new Node);
        Node_SP n2 = std::shared_ptr<Node>(new Node);

        n1->set_root(*n2);
    }
Run Code Online (Sandbox Code Playgroud)

Arn*_*rtz 5

为此,enable_shared_from_this<Node>必须自己存储一个weak_ptr<Node>。这weak_ptr是缺省构造为空。当shared_ptr构造a来接管对象的所有权时,无论是通过vía make_shared还是通过传递原始指针,它都会设置表示weak_ptr引用该new shared_ptr。如果随后调用shared_from_this()该对象,则可以返回weak_ptrgets locked和另一个shared_ptr

然而,你的情况不存在shared_ptr控股n1n2,调用所以当shared_from_this()lock大干快上的空运行weak_ptr,导致表示异常。

长话短说:不要调用shared_from_this()不是由a拥有的对象shared_ptr-尤其是在您的示例中,不要调用基于堆栈的对象。