在开发类似树的数据结构时,我写了类似的东西:
#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);
}
代码使用 clang 进行编译,但会破坏运行时(“libc ++ abi.dylib:以std :: __ 1 :: bad_weak_ptr:bad_weak_ptr类型的未捕获异常终止”)< / strong>为什么?
修改 所以根据答案,我想出了似乎有效的版本:
#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);
}
答案 0 :(得分:4)
为了完成这项工作,enable_shared_from_this<Node>
必须为自己存储weak_ptr<Node>
。此weak_ptr
默认构造为null。当构造shared_ptr
来接管对象的所有权时,无论是make_shared
还是通过传递原始指针,它都会设置weak_ptr
来引用新的shared_ptr
。如果您随后在对象上调用shared_from_this()
,则weak_ptr
会获得lock
,并且可以返回另一个shared_ptr
。
但是,在您的情况下,没有shared_ptr
持有n1
和n2
,因此在调用shared_from_this()
时,lock
会在空weak_ptr
上执行shared_from_this()
1}},导致所述异常。
长话短说:不要在不属于shared_ptr
的对象上调用{{1}} - 尤其不要在示例中基于堆栈的对象上调用。 / p>
答案 1 :(得分:2)
在对象t上调用shared_from_this之前,必须有一个拥有t的std :: shared_ptr。
答案 2 :(得分:1)
shared_ptr
假设对象已在堆上分配,但您已将其分配到堆栈上。
改为使用new
,让shared_ptr
为您致电delete
。