简体   繁体   English

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

[英]c++ Observer Pattern: raw pointers vs shared_ptr?

I'm in the process of converting (at least) some of my code to using shared_ptr. 我正在将(至少)我的一些代码转换为使用shared_ptr。 However I'm running into an issue with the Observer pattern which I'm using. 但是我遇到了我正在使用的Observer模式的问题。

I have a presenter class (Model View Presenter) which implements the Observer pattern and it gets notified when certain events happens. 我有一个演示者类(Model View Presenter),它实现了Observer模式,并在某些事件发生时得到通知。 I wrote generic Subject/Observer classes that any class can inherit from. 我编写了任何类都可以继承的通用Subject / Observer类。 The update method looks something like this: update方法如下所示:

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

}

This worked fine until I converted myService_ (a member of MyPresenter class) to a std::shared_ptr . 这工作正常,直到我将myService_ (MyPresenter类的成员)转换为std::shared_ptr Now the expression (subject == myService_) is no longer valid. 现在表达式(subject == myService_)不再有效。

I may eventually convert everything to shared_ptr, but until then is there an easy way for me to support both raw pointers and shared_ptr's with the Observer pattern? 我最终可能会将所有内容转换为shared_ptr,但在此之前,我是否有一种简单的方法来支持原始指针和带有Observer模式的shared_ptr? Ideally I'd like the observer pattern to be agnostic to the observer's pointer implementation but maybe that's not possible. 理想情况下,我希望观察者模式与观察者的指针实现无关,但也许这是不可能的。 How can I fix this? 我怎样才能解决这个问题?

UPDATE UPDATE

Should an observer pattern Observer interface take a shared pointer? 观察者模式Observer接口应该采用共享指针吗? Or is it better to keep it as raw pointers? 或者将它作为原始指针更好? Currently I have: 目前我有:

class Subject;

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

protected:
    Observer() {}
};

To get this working myService_ and subject needs to be shared_ptr. 为了使这个工作myService_和主题需要是shared_ptr。 Otherwise you can try to compare it like this, if subject and shared_ptr points to the same object. 否则,如果subject和shared_ptr指向同一个对象,您可以尝试比较它。

  subject == myService_.get()

Otherwise try to change all pointers to shared_ptr. 否则尝试将所有指针更改为shared_ptr。

You can use shared_ptr 's get member, which returns the raw pointer that the shared_ptr wraps: 你可以使用shared_ptr的get成员,它返回shared_ptr包装的原始指针:

subject == myService_.get()

In general I would not suggest to blindly convert all raw pointers to shared_ptr s. 一般来说,我不建议盲目地将所有原始指针转换为shared_ptr You always have to think about if the surrounding object really owns the pointed by object (and shared ownership is still ownership). 你总是要考虑周围的对象是否真的拥有指向的对象(并且共享所有权仍然是所有权)。 Sometimes a std::unique_ptr (although I don't know if tr1 already has that, otherwise a std::auto_ptr ) is a better choice, if it is strict ownership or also just a raw pointer, if it is no ownership. 有时std::unique_ptr (虽然我不知道tr1已经有了,否则std::auto_ptr )是一个更好的选择,如果它是严格的所有权或者只是一个原始指针,如果它不是所有权。

But in interfaces, especially function arguments and return values, raw pointers are often a better idea than using smart pointers and thus decreasing genericity (and also performance, though only insignificantly, but even more so for shared_ptr 's). 但是在接口中,特别是函数参数和返回值,原始指针通常比使用智能指针更好,因此降低了通用性(以及性能,虽然只是微不足道,但对于shared_ptr更是如此)。

NOTE: I know this is the same answer as the already existing one, but I desperately felt the need against just suggesting to use shared_ptr s all over the place. 注意:我知道这和现有的答案是一样的,但我绝对觉得有必要不要建议在所有地方使用shared_ptr

Why not simply lets the model inherit from std::enable_shared_from_this . 为什么不简单地让模型继承自std::enable_shared_from_this If ownership is shared anyways, then shared_from_this can be returned from a (possibly virtual) method of the model. 如果所有权共享,则可以从模型的(可能是虚拟的)方法返回shared_from_this Beware, this has some restrictions for the constructor of the model however. 请注意,这对模型的构造函数有一些限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM