2012-06-01 5 views
2

나는 작은 클래스 계층 구조를 가지고 있으며 소유권을 유지하는 간단한 방법을 찾으려고합니다. 이 객체들은 힙에 존재하고 원시 포인터를 싫어하기 때문에 공유 포인터와 약한 포인터를 사용합니다. (나는 대안에 대해 개방적이지만, 익숙한 방법이다.) 공유 포인터의 소유자가 그렇게 말할 때 약한 포인터가 객체가 삭제되는 것을 방지하지 않기 때문에 공유 포인터가 소유권을 도울 수있다.목록에서 자신을 추가하고 제거하는 객체들

계층 구조 :

class Actor; 
class Body : public virtual Actor; 
class Owned : public virtual Actor; 
class Combatant : public Body, public Owned; 

도가 다른 클래스가있다. 가상 상속을 사용하여 다이아몬드 상속을 처리 할 수 ​​있으므로 큰 문제는 아닙니다. 또한 각각에 대해 shared_ptrs 및 weak_ptrs를 typedef로 지정하겠습니다.

내 생각은 Actor가 Actor 공유 포인터 (ActorPTR)의 정적 목록을 유지하고 자식 클래스가 weak 포인터 (BodyWPTR 등)의 정적 목록을 유지하도록하는 것입니다. 이렇게하면 공유 포인터의 확실한 컬렉션이 있습니다. 어떤 종류의 소유권도 관리해야합니다. (다른 곳에서는 공유 포인터를 영구적으로 저장하지 않으려 고 노력할 것입니다.)이 목록을 가지고 있으면 "근처의 모든 전투원을 얻으십시오"또는 "모든 시체를 이동하십시오"라고 신속하게 말할 수 있기 때문에 유용합니다.

올바른 목록에 개체를 삽입하고 싶습니다. Body는 약한 포인터 목록에 자체의 약한 포인터를 삽입하고 해당 목록에 Actor 공유 포인터를 삽입합니다. 건설자. 하지만 (분명히) "this"포인터 (또는 shared_from_this()와 동등한 것)를 생성자에서 사용하는 것은 나쁜 모조입니다. 내가 그것을 할 수 있다고 생각할 수있는 유일한 방법은 모든 공장 ​​방법을 사용하는 것입니다. 또한 계층 구조에있는 여러 클래스를 enable_shared_from_this에서 상속받는 것이 좋지 않을 수도 있습니다.

생성자 중에 개체가 공유 또는 약한 포인터를 목록에 자동으로 삽입하도록하려면 어떻게해야합니까? 그게 나쁜 생각이야?

은 (또한 "코드"에서 위, 나는 가상 상속 구문을 엉망 수도 있지만 내가 지금 걱정 해요 무엇을하지, 그래서 그것에 대해 걱정하지 마십시오.)

감사합니다!

MyClass *c = myNew<MyClass>(); 
+1

정리 전략에 대해 말하지 않고 메모리 관리 전략을 말할 수는 없습니다. 그대로, Actor의 정적 목록은 모든 액터를 영원히 살아있게합니다 (메모리 누수와 유사). 일단 당신이 정리를 다루는 전략을 노출하면, 우리는 적절하게 대답 할 수 있습니다. (제 의견에 응답 해주세요. –

+0

.액터는 일종의 destroy() 메소드를 가지고 있기 때문에리스트에서 자신을 제거 할 수 있습니다. 이렇게하면 배우가 필요할 때 청소할 수 있습니다. 유일한 영구 공유 포인터 인 경우 삭제해야하며 약 포인터 목록을 반복 할 때 만료 된 포인터를 지울 수 있습니다. – whiterook6

+0

그건 이상한 일이지만 왜 안되는거야. 효율성을 위해서'Actor'는'destroy'가 O (1)가되도록 반복자를 목록에 삽입해야합니다. 여전히'destroy()'를 호출하고 메모리 누수가 발생하는 것을 잊어 버릴 위험이 있습니다. –

답변

1

당신은 템플릿을 사용하여 하나의 공장 방법을 사용할 수 있습니다.

당신의 문제는 당신이 묻는 구체적인 질문이 아니라 귀하의 디자인이라고 생각합니다. 근본적으로, 당신은 전역을 사용하고 있으며, 그것은 보통 나쁜 생각입니다. 실제로 어떤 종류의 World 개체가 있어야하며 그 중 하나 인 World은 전 세계 모든 액터의 컬렉션, 모든 본문 목록 등입니다.

일반적인 구성은 예를 들어 새로운 Combatant을 만들고이를 세계에 채우는 것과 같습니다. 또는 귀하의 세계가 spawnCombatant 일 수도 있습니다.

1

난 당신이 약한 포인터를 귀찮게하는 이유를 이해하지 않습니다

template <typename T> 
T *myNew() { 
    T *t = new T(); 
    t->push_to_list(); 
    return t; 
} 

다음과 같이 호출 :

+0

세계 객체를 사용하는 경우 모든 사람이 액세스 할 수 있도록 싱글 톤 또는 정적 메서드가 필요합니다 (다른 사람들이 액세스해야하는 getCombatants()와 같은 메서드가 있음). 어쨌든, 나는 그것이 여전히 글로벌 가치라고 생각합니다. – whiterook6

관련 문제