2013-06-25 39 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)。 做检查的参考,因为题目不能完全在两行覆盖。

标准库为程序员提供两个双FF erent类(事实上,有也是其他智能指针),即shared_ptrweak_ptr。共享指针是一个智能指针,用于保存指向对象的指针和指向共享引用计数器的附加指针。每当智能指针的副本 被创建时,引用计数自动增加1.当共享指针被销毁(或用于引用不同对象)时,其对象的引用计数器(或用于 其先前的对象)递减。从原始 构建的共享指针最初的引用计数为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超出范围时,分解器不会调用因为cv->controller)和vc->view)仍有一个参考。

这个解决方案用两个词来代替两个shared_ptr中的一个与weak_ptr。当然,你不只是随意偷看其中的一个,取而代之的是取决于你的设计,你最终可能会取代它们(这一切都取决于所有权semanthics)。但是,如果您(至少)替换其中一个,问题就解决了。

同样applyies你拥有所有的参考周期在您的设计