我还没有在任何主要的 C++ 论坛/博客上找到以下打破循环引用的方法,比如在 GotW 上,所以我想问一下这种技术是否已知,它的优缺点是什么?
class Node : public std::enable_shared_from_this<Node> {
public:
std::shared_ptr<Node> getParent() {
return parent.lock();
}
// the getter functions ensure that "parent" always stays alive!
std::shared_ptr<Node> getLeft() {
return std::shared_ptr<Node>(shared_from_this(), left.get());
}
std::shared_ptr<Node> getRight() {
return std::shared_ptr<Node>(shared_from_this(), right.get());
}
// add children.. never let them out except by the getter functions!
public:
std::shared_ptr<Node> getOrCreateLeft() {
if(auto p = getLeft())
return p;
left = std::make_shared<Node>();
left->parent = shared_from_this();
return getLeft();
}
std::shared_ptr<Node> getOrCreateRight() {
if(auto p = getRight())
return p;
right = std::make_shared<Node>();
right->parent = shared_from_this();
return getRight();
}
private:
std::weak_ptr<Node> parent;
std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
};
从外部看,用户Node
不会注意到在getLeft
and中使用别名构造函数的技巧getRight
,但用户仍然可以确定getParent
总是返回一个非空共享指针,因为返回的所有指针都会在 的生命周期内p->get{Left,Right}
保持对象处于活动状态*p
返回的子指针。
我是否在这里忽略了某些东西,或者这是打破已经记录的循环引用的明显方法?
int main() {
auto n = std::make_shared<Node>();
auto c = n->getOrCreateLeft();
// c->getParent will always return non-null even if n is reset()!
}