2011-10-31 89 views
1

我正在将(至少)一些代码转换为使用shared_ptr。然而,我遇到了我正在使用的Observer模式的问题。C++观察者模式:原始指针vs shared_ptr?

我有一个演示者类(Model View Presenter),它实现了观察者模式,并在某些事件发生时得到通知。我编写了任何类都可以继承的通用Subject/Observer类。更新方法看起来是这样的:

void MyPresenter::Update(Subject *subject) 
{ 
    if(subject == myService_) 
    { 
     DoSomething(); 
    } 
    else if(subject == myOtherService_) 
    { 
     DoSomethingElse(); 
    } 

} 

这工作得很好,直到我转换myService_(MyPresenter类的成员)到std::shared_ptr。现在表达式(subject == myService_)不再有效。

我最终可能会将所有内容都转换为shared_ptr,但在那之前有一个简单的方法可以让我使用Observer模式支持raw指针和shared_ptr两者?理想情况下,我希望观察者模式对观察者的指针实现不可知,但也许这是不可能的。我怎样才能解决这个问题?

UPDATE

如果观察者图案Observer接口采取共享指针?还是更好地保持它作为原始指针?目前我有:

class Subject; 

class Observer 
{ 
public: 
    virtual ~Observer() {} 
    virtual void Update(Subject *subject) = 0; 

protected: 
    Observer() {} 
}; 

回答

1

您可以使用shared_ptr的获取成员,返回原始指针的shared_ptr包装:

subject == myService_.get() 

一般来说,我不会建议对所有原始指针盲目地转换为shared_ptr秒。你总是必须考虑周围的对象是否真的拥有指向的对象(并且共享所有权仍然是所有权)。有时一个std::unique_ptr(虽然我不知道tr1已经有这个,否则std::auto_ptr)是一个更好的选择,如果它是严格的所有权或只是一个原始指针,如果它没有所有权。

但是在接口中,特别是函数参数和返回值,原始指针通常比使用智能指针更好,因此降低了通用性(并且性能也尽管只有微不足道,但对于shared_ptr更是如此)。

注意:我知道这是与现有的答案相同的答案,但我绝望地感到需要反对只是建议在所有地方使用shared_ptr s。

+0

使用Visual Studio 2010,我刚刚发现我可以使用'std :: shared_ptr'而不是'std :: tr1 :: shared_ptr'。 'unique_ptr'也是可用的。 – User

+0

我来自C#,我真的得到关于shared_ptr的混合消息。一方面,人们说,编写无漏洞的代码真的很难,特别是当你考虑各种异常情况时,另一方面人们说不要使用它太多。尽管除了性能上的缺点,我还不太清楚使用智能指针的缺点。 – User

+0

@User这会降低灵活性,因为如果函数参数需要一个参数,您总是必须传入'shared_ptr',但它不是必需的。在没有所有权语义(也就是共享所有权)的情况下也使用'shared_ptr'-成员是最好的情况,在概念上是错误的,最坏的情况下会导致明显的错误(尽量不要使用智能指针来处理动态分配的对象)。 –

3

为了使这项工作myService_和主题需要被shared_ptr。否则,您可以尝试像这样比较它,如果subject和shared_ptr指向同一个对象。

subject == myService_.get() 

否则,请尝试更改所有指向shared_ptr的指针。

0

为什么不简单让模型继承std::enable_shared_from_this。如果所有权无论如何共享,那么shared_from_this可以从模型的(可能是虚拟的)方法返回。请注意,这对模型的构造函数有一些限制。