c++观察者模式:原始指针vs shared_ptr

c++ Observer Pattern: raw pointers vs shared_ptr?

本文关键字:shared ptr vs 指针 观察者模式 原始 c++      更新时间:2023-10-16

我正在转换(至少)我的一些代码来使用shared_ptr。然而,我遇到了一个问题与观察者模式,我正在使用。

我有一个演示器类(模型视图演示器),它实现了观察者模式,当某些事件发生时它会得到通知。我编写了任何类都可以继承的通用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,但在此之前,是否有一种简单的方法让我支持原始指针和shared_ptr的观察者模式?理想情况下,我希望观察者模式是不可知的观察者的指针实现,但也许这是不可能的。我该如何解决这个问题?

观察者模式的观察者接口应该使用共享指针吗?还是将其保留为原始指针更好?目前我有:
class Subject;
class Observer
{
public:
    virtual ~Observer() {}
    virtual void Update(Subject *subject) = 0;
protected:
    Observer() {}
};

要得到这个工作myService_和主题需要是shared_ptr。如果subject和shared_ptr指向同一个对象,则可以这样比较:

  subject == myService_.get()

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

subject == myService_.get()
一般来说,我不建议盲目地将所有原始指针转换为shared_ptr s。您总是需要考虑周围对象是否真的拥有指向对象(共享所有权仍然是所有权)。有时std::unique_ptr(虽然我不知道tr1是否已经有了,否则std::auto_ptr)是一个更好的选择,如果它是严格的所有权,或者只是一个原始指针,如果它没有所有权。

但是在接口中,特别是函数参数和返回值中,原始指针通常比使用智能指针更好,因此会降低泛型(以及性能,虽然不是很明显,但对于shared_ptr来说更是如此)。

注意:我知道这和已经存在的答案是一样的,但是我迫切地觉得有必要反对仅仅建议在所有地方使用shared_ptr s

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