2013-02-22 4 views
3

나는 각 레벨마다 다른 클래스를 사용하여 트리를 구현했다. 트리 항목에 대한 포인터는 boost :: shared_ptr <>입니다.boost :: shared_ptr circular dependency

각 레벨은 상위에 대한 포인터와 하위에 대한 포인터를 저장하기 때문에 헤더 파일에 순환 종속성이 있습니다.

코드는 다음과 같습니다

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

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

}; 

은 내가 B.hhp에서 선언을 앞으로 사용할 수 없습니다 부스트 :: shared_ptr을 사용하기 때문에. 하지만이 문제를 해결하는 방법을 모르겠습니다. 네가 나를 도울 수 있다면 좋을거야.

+1

힌트 : 자녀가 부모를 소유하고 있습니까? 그렇지 않다면 부모에게 포인터를 가지고있는 이유는 무엇입니까? –

+1

물론 아이들은 부모를 소유해서는 안됩니다.이 포인터를 위해 다른 종류의 포인터가 필요합니까? – Thorsten

+0

클래스 A에 대한 일반적인 포인터가 왜 안되나요? – abellina

답변

5

내가 부스트 :: shared_ptr을 사용하기 때문에 나는이 사실이 아니라는 B.hhp

에서 선언을 앞으로 사용할 수 없습니다. shared_ptr<>를 선언하는 것은 완료하기 위해 뾰족한 형태를 필요가 없습니다 :

#include <boost/shared_ptr.hpp> 

class A; 

int main() 
{ 
    boost::shared_ptr<A> pA; // OK 
} 

class A { }; 

귀하의 문제는 헤더 파일에 대한 상호 의존성으로하지 않습니다. 당신은 확실히 을 사용하여 forward-declarations를 사용하여 그 의존성을 깨뜨릴 수 있습니다.

당신이 가지고있는 문제는 서로 살아있는 개체 사이의 순환 참조입니다. 이주기를 깨기 위해서는 boost::weak_ptr을 사용하십시오. 또한

, C++ (11)가 표준 클래스 템플릿을 소개합니다 ( <memory> 헤더에 정의) std::shared_ptrstd::weak_ptr, 그래서 당신은 C++ 03로 작업하지 않는 대신 부스트의 사람의이 클래스 템플릿을 사용하는 것이 좋습니다.

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

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

이 솔루션은 컴파일하는 것 같아요, 아직 종속성을 확인하지 않았습니다. 신속한 답변을 주신 모든 분들께 감사드립니다. 그것은 지금 스마트 포인터에 대해 더 알아야합니다;) – Thorsten

+0

@Thorsten : OK, 행운을 빕니다 :-) –

2

당신은 사이클을 깰 Bboost::weak_ptr을 사용해야합니다

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

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

그것은 convertedlock() 방법 boost::shared_ptr<A>에 할 수있다.

0

자식에서 부모까지의 포인터 (트리를 "위로"이동하는 포인터)는 boost::weak_ptr이어야합니다. 그것은 boost :: shared_ptrs (weak_ptr :: lock() 함수를 통해)를 통해 부모를 액세스 가능한 상태로 유지하면서 원형 종속성을 효과적으로 무너 뜨릴 것입니다.

0

이것은 스마트 포인터로 클래식합니다. 종속성을 깨기 위해서는 어느 방향 으로든 weak_ptr을 사용해야합니다.

작동 방식은 weak_ptr입니다. 아니요,은 뾰족한 개체에 대한 참조를 보유하고 있습니다. 그러나 언제든지 .lock() 함수를 호출하여 shared_ptr을 얻을 수 있습니다. 어떻게 든 shared_ptr이 만료 된 후에 .lock() 후에 호출하지 않도록 조심해야합니다.

내가 사용하는 방식은 다음과 같습니다. 항상 부모님과 자녀가 만나는 shared_ptr, 자녀는 부모님과 항상 weak_ptr을 유지해야합니다.따라서 계층 구조에서 하드 링크를 수행 할 수 없으므로 순환 종속성을 가질 수 없습니다.

이 방법은 의미가 있습니다 (특정 상황에 따라 다를 수 있음). 자식이 존재하면 부모가 계속 존재해야하므로 weak_ptr에있는 .lock()을 호출해도 실패하지 않습니다.

weak_ptr 등의 자세한 내용은 Boost documentation에서 확인할 수 있습니다.

관련 문제