2013-06-25 5 views
3

내 MVC 구조를 만들려고합니다. 나는 처음으로 shared_ptr과 weak_ptr을 사용하고 있으며 순환 종속성 외에도 많은 문제점을 가지고있다.MVC에서 순환 종속성 :: shared_ptr

모델은 관찰 가능합니다. 보기는 옵저버입니다.

class Observable 
{ 
    std::set< std::shared_ptr<Observer> > observers; 
public: 
    Observable(void); 
    void registerObserver(std::shared_ptr<Observer> ); 
    void removeObserver(std::shared_ptr<Observer> &); 
    void notifyObservers(void); 
    virtual ~Observable(void); 
}; 


class Observer 
{ 
public: 
    Observer(void); 
    virtual void update() = 0; 
    virtual ~Observer(void); 
}; 

    class Model : public Observable 
{ 
public: 
    Model(void); 
    void internalStateChange(); 
    void funcForController(); 
    int getSomethingForView() const; 
    ~Model(void); 
}; 

class View : 
public Observer 
{ 
std::weak_ptr<Model> model; 
std::shared_ptr<Controller> controller; 
public: 
View(const std::shared_ptr<Model> &, const std::shared_ptr<Controller> &); 
void update() override; 
~View(void); 
}; 

class Controller 
{ 
std::shared_ptr<Model> model; 
std::shared_ptr<View> view; 
public: 
Controller(std::shared_ptr<Model> &); 
void changeHappened() const; 
~Controller(void); 
}; 

내 출력은 다음과 같습니다 enter image description here

이 어딘가에 다음은 다른 출력 종료 50초 같은 후 걸려 보여줍니다. enter image description here

컨트롤러가 파괴되지 않습니다. :(

어떻게?

+0

에서 당신이 가지고있는 모든 참조 사이클 같은 applyies ['표준을 :: weak_ptr'] (http://en.cppreference.com/w/cpp/memory/weak_ptr)? –

+0

어디에서 사용해야합니까? 보기에 모델 용으로 사용하고 있습니다. –

답변

0

문제가 아니라 너무 부스트 문서에 설명되어 문제를 해결 않기 때문에보고 있습니다. 을 나 자신이 기준을 위반 약세 포인터의 사용에 매우 빠른 메모를 썼다 내 마스터 논문에 부록으로주기는 (그것을 here를 찾을 수 있습니다). 을 주제 완전히 두 줄에 적용되지 않을 수 있기 때문에, 참조를 확인 마십시오.

표준 라이브러리 사실 (이 개 디 FF의 서로 다른 클래스와 프로그래머를 제공하며,이 다른 스마트 포인터도 있습니다) 즉 shared_ptrweak_ptr. 공유 포인터는 개체에 대한 포인터와 공유 참조 카운터에 대한 추가 포인터를 유지하는 스마트 포인터입니다. 스마트 포인터 복사본이 만들어 질 때마다 참조 카운트는 자동으로 이 증가합니다. 공유 포인터가 파괴되면 (또는 다른 개체를 참조하기 위해 사용되는 경우) 해당 개체에 대한 참조 카운터 (또는 이전 개체)가 감소됩니다. 원래 포인터로 구성된 공유 포인터는 처음에 참조 횟수가 1입니다. 참조 카운터 이 0에 도달하면 뾰족한 개체가 자동으로 삭제됩니다. 루프를 참조 구조로 분리하기 위해 약한 포인터는 입니다. 은 동일한 개체에 대한 공유 포인터를 얻고 개체가 이미 파괴되었는지 여부를 확인하는 데 사용할 수 있습니다. 그들은 참조 카운팅을 포함하지 않습니다. 약한 포인터는 직접 참조 해제되지 않습니다. 즉, 참조 된 객체에 액세스하기 위해 을 사용할 수 없으므로 충돌 또는 임의의 동작이 발생할 수 있으며 실제로 포인터가 매달릴 수 있습니다.

특정 문제에 관해서는

, 요점은 이것이다 : 당신이 클래스

class Controller 
{ 
public: 
std::shared_ptr<View> view; 
}; 

및 다른 클래스가 : 당신이 서로를 "지정"

class View : 
public Observer 
{ 
public: 
std::shared_ptr<Controller> controller; 
}; 

과를, 즉

std::shared_ptr<Controller> c(new Controller); 
std::shared_ptr<View> v(new View); 
c->view = v; 
v->controller = c; 

cv이 범위를 벗어나면 방해받지 않는 사용자는 전화를 걸지 않습니다. c (v->controller)과 v (c->view)에 대한 참조가 여전히 존재하기 때문에 에드.

두 개의 단어로, shared_ptr 중 하나를 weak_ptr으로 대체하는 것이 해결책입니다. 물론 두 가지 중 하나를 무작위로 엿보는 것은 아닙니다. 대체 할 디자인은 디자인에 따라 다르며 둘 모두를 대체하게됩니다 (모두 소유권 의미론에 따라 다름). 그러나, 당신이 그들 중 하나 (적어도)를 대체하면, 문제는 해결됩니다.

사용 고려하여 디자인