在开发树状数据结构时,我写了这样的内容:
#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)
为此,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控股n1和n2,调用所以当shared_from_this()在lock大干快上的空运行weak_ptr,导致表示异常。
长话短说:不要调用shared_from_this()不是由a拥有的对象shared_ptr-尤其是在您的示例中,不要调用基于堆栈的对象。