3

我有一个问题,我在每个级别使用不同的类实现了一棵树。指向树项的指针是 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 中使用前向声明。但我不知道如何解决这个问题。如果你能帮助我,那就太好了。

4

4 回答 4

5

因为我使用 boost::shared_ptr 我不能在 B.hhp 中使用前向声明

这不是真的。声明 ashared_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_ptrstd::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;
};
于 2013-02-22T20:57:41.793 回答
2

您应该使用boost::weak_ptrinB来打破循环:

//A.hpp
class A
{
    List<boost::shared_ptr<B> > children;
};

//B.hpp
class B
{
   boost::weak_ptr<A> parent;
};

可以用方法转换成。boost::shared_ptr<A>lock()

于 2013-02-22T20:57:14.150 回答
0

从孩子到父母的指针(那些“向上”树的指针)应该是boost::weak_ptr。这将有效地打破你的循环依赖,同时仍然可以通过 boost::shared_ptrs (通过weak_ptr::lock() 函数)访问父母。

于 2013-02-22T20:58:03.650 回答
0

这是经典的智能指针。您必须以某种方式weak_ptr在某个方向上使用来打破依赖关系。

它的工作方式是weak_ptr持有指向对象的引用。但是你可以在任何给定时间通过调用它的函数来获得。你必须小心,但不要在不知何故过期后打电话。shared_ptr.lock().lock() shared_ptr

我使用这种机制的方式如下:你总是对shared_ptr你的父母不给你的孩子,你总是对weak_ptr你的孩子不给你的父母。所以你永远不会有循环依赖,因为你不能在你的层次结构中做一个硬链接。

这种方式是有道理的(但它可能会根据您的特定情况而有所不同):如果孩子存在,那么父母必须仍然存在,因此调用.lock()不会weak_ptr失败。

weak_ptr您可以在Boost 文档中了解更多信息。

于 2013-02-22T21:02:52.523 回答