2013-02-22 134 views
3

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

+1

提示:孩子们是否拥有父母?如果没有,那为什么他们拥有指向父母的指针呢? – 2013-02-22 20:53:53

+1

当然,孩子们不应该拥有父母,我需要另一种类型的指针吗? – Thorsten 2013-02-22 20:56:28

+0

为什么不用常规指针指向类A? – abellina 2013-02-22 20:56:49

回答

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_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; 
}; 
+0

此解决方案似乎编译,我还没有检查依赖关系。谢谢你和所有其他人的快速回复。它应该更多地了解智能指针;) – Thorsten 2013-02-22 21:09:05

+0

@Thorsten:好的,祝你好运:-) – 2013-02-22 21:09:56

2

你应该B使用boost::weak_ptr打破循环:

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

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

它可以convertedboost::shared_ptr<A>lock()方法。

0

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

0

这是古典与智能指针。你必须以某种方式使用weak_ptr来打破依赖。

它的工作方式是weak_ptr确实不是持有对指向对象的引用。但是,您可以在任何时候通过调用其.lock()函数获得shared_ptr。你必须小心,尽管不要在之后.lock()shared_ptr过期。

我使用这种机制的方式如下:您始终保持shared_ptr从您的父母到您的孩子,并且您始终将weak_ptr从您的孩子保留给您的父母。所以你从来没有循环依赖,因为你不能在你的层次结构中做一个硬链接。

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

您可以通过weak_ptr等了解更多Boost documentation