使用时有哪些方式可能会搬起石头砸自己的脚boost::shared_ptr http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm?换句话说,我在使用时要避免哪些陷阱boost::shared_ptr http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm?
循环引用:ashared_ptr<>
到有一个东西shared_ptr<>
到原始对象。您可以使用weak_ptr<>
当然,要打破这个循环。
我添加以下内容作为我在评论中谈论的内容的示例。
class node : public enable_shared_from_this<node> {
public :
void set_parent(shared_ptr<node> parent) { parent_ = parent; }
void add_child(shared_ptr<node> child) {
children_.push_back(child);
child->set_parent(shared_from_this());
}
void frob() {
do_frob();
if (parent_) parent_->frob();
}
private :
void do_frob();
shared_ptr<node> parent_;
vector< shared_ptr<node> > children_;
};
在此示例中,您有一个节点树,每个节点都保存一个指向其父节点的指针。无论出于何种原因,frob() 成员函数都会在树中向上传递。 (这并不完全奇怪;一些 GUI 框架就是这样工作的)。
问题是,如果失去对最顶层节点的引用,那么最顶层节点仍然保留对其子节点的强引用,并且其所有子节点也保留对其父节点的强引用。这意味着存在循环引用,使所有实例无法自行清理,而无法从代码中实际到达树,这种内存泄漏。
class node : public enable_shared_from_this<node> {
public :
void set_parent(shared_ptr<node> parent) { parent_ = parent; }
void add_child(shared_ptr<node> child) {
children_.push_back(child);
child->set_parent(shared_from_this());
}
void frob() {
do_frob();
shared_ptr<node> parent = parent_.lock(); // Note: parent_.lock()
if (parent) parent->frob();
}
private :
void do_frob();
weak_ptr<node> parent_; // Note: now a weak_ptr<>
vector< shared_ptr<node> > children_;
};
这里,父节点已被弱指针取代。它对其所引用的节点的生命周期不再有发言权。因此,如果最顶层的节点像前面的示例一样超出了范围,那么虽然它拥有对其子节点的强引用,但其子节点不会对其父节点保持强引用。因此,没有对该对象的强引用,并且它会自行清理。反过来,这会导致孩子们失去一个强有力的参考,从而导致他们清理干净,等等。简而言之,这不会泄漏。只需战略性地用weak_ptr替换shared_ptr。
注意:上述内容同样适用于 std::shared_ptr 和 std::weak_ptr,就像它适用于 boost::shared_ptr 和 boost::weak_ptr 一样。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)