我有一个问题,我在每个级别使用不同的类实现了一个树。 指向树项的指针是boost :: shared_ptr<>。
因为每个级别都存储一个指向父级的指针和一个指向其子级的指针,所以在头文件中存在循环依赖关系。
代码如下所示:
//A.hpp
class A
{
List<boost::shared_ptr<B> > children;
};
//B.hpp
class B{
boost::shared_ptr<A> parent;
};
因为我使用boost :: shared_ptr我不能在B.hhp中使用前向声明。但我不知道如何解决这个问题。如果你能帮助我,那就太好了。
答案 0 :(得分:5)
因为我使用boost :: shared_ptr我不能在B.hhp中使用前向声明
事实并非如此。声明shared_ptr<>
不应该要求指向的类型完成:
#include <boost/shared_ptr.hpp>
class A;
int main()
{
boost::shared_ptr<A> pA; // OK
}
class A { };
您的问题不在于对头文件的相互依赖。你肯定可以使用前向声明来打破这些依赖。
您遇到的问题是在彼此保持活动的对象之间进行循环引用。要打破此周期,请使用boost::weak_ptr
。
此外,C ++ 11引入了标准类模板std::shared_ptr
和std::weak_ptr
(在<memory>
标题中定义),所以除非您使用的是C ++ 03,否则应该考虑使用这些类模板而不是Boost的模板。
//A.hpp
class A
{
List<boost::shared_ptr<B> > children;
};
//B.hpp
class B{
boost::weak_ptr<A> parent;
};
答案 1 :(得分:2)
您应该使用B
中的boost::weak_ptr
来打破周期:
//A.hpp
class A
{
List<boost::shared_ptr<B> > children;
};
//B.hpp
class B
{
boost::weak_ptr<A> parent;
};
使用boost::shared_ptr<A>
方法可以converted到lock()
。
答案 2 :(得分:0)
从子节点到父节点的指针(那些“向上”树的指针)应该是boost::weak_ptr。这将有效地打破你的循环依赖,同时仍然可以通过boost :: shared_ptrs(通过weak_ptr :: lock()函数)访问父项。
答案 3 :(得分:0)
这是经典的智能指针。你必须以某种方式使用weak_ptr
来打破依赖。
它的工作方式是weak_ptr
不保持对指向对象的引用。但是,您可以通过调用shared_ptr
函数在任何给定时间获得.lock()
。您必须小心,但在 .lock()
以某种方式过期后不要致电shared_ptr
。
我使用这种机制的方式如下:你总是将父母shared_ptr
留给你的孩子,你总是从你的孩子那里weak_ptr
给你的父母。因此,您永远不会有循环依赖,因为您无法在层次结构中返回硬链接。
这种方式有意义(但可能因您的具体情况而异):如果子项存在,则父项必须仍然存在,因此.lock()
上的weak_ptr
调用不会失败。< / p>
您可以在weak_ptr
上详细了解Boost documentation。