2013-06-25 2 views
3

Я пытаюсь создать эту структуру MVC для своего проекта. Я использую shared_ptr и weak_ptr в первый раз и получаю много проблем, кроме круговой зависимости.Циркулярная зависимость в MVC std :: 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

Продуманные с помощью [ 'зОго :: weak_ptr'] (http://en.cppreference.com/w/cpp/memory/weak_ptr)? –

+0

Я не понимаю, где его использовать? Я использую его для рассматриваемой модели. –

ответ

0

вопрос хорошо документированный в документации повышающего тоже, так что посмотрим. я сам написал очень быстро записку об использовании слабых указателей для взлома ссылки циклы в качестве приложения в магистерской диссертации (найти его here). ли проверить ссылки, так как эта тема не может быть полностью покрыты два линий.

стандартная библиотека предоставляет программист два ди-классы и далее различен (в самом деле, также являются другими интеллектуальными указателями), а именно shared_ptr и weak_ptr. Общий указатель - это умный указатель, содержащий указатель на объект и дополнительный указатель на общий счетчик ссылок. Каждый раз, когда выполняется копия умного указателя, счетчик ссылок автоматически увеличивается на 1. Когда общий указатель уничтожается (или используется для ссылки на другой объект), счетчик ссылок для своего объекта (или тот, который для его предыдущий объект) уменьшается. Общие указатели, построенные в форме raw , указатели первоначально имеют счетчик ссылок 1. Когда контрольный счетчик достигает 0, заостренный объект автоматически уничтожается. Слабые указатели - это , используемые для разбиения петель на структуру ссылок. Они могут быть , используемые для получения общего указателя на тот же объект и проверки того, был ли объект уже уничтожен. Они не включают подсчет ссылок. Слабые указатели не предназначены для прямой разыменования (т. Е. Они не могут использовать , чтобы получить доступ к указанному объекту, так как это может привести к авариям или случайному поведению, они могут, по сути, обвиснуть pointerst).

Что касается конкретной проблемы, точка зрения такова: у вас есть класс

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; 

, когда c и v выходят из сферы действия. так как имеется еще одна ссылка для c (v->controller) и одна для v (c->view).

Решение, в двух словах, должно заменить один из двух shared_ptr s на weak_ptr. Конечно, вы не просто заглядываете в одного из двух случайных людей, а подзаголовок зависит от вашего дизайна, и вы вполне можете заменить их обоих (все зависит от семантики собственности). Однако, если вы замените (по крайней мере) один из них, проблема будет решена.

Той же applyies для всех опорных циклов вы имеете в вашем дизайне