I'm in the process of converting (at least) some of my code to using shared_ptr. However I'm running into an issue with the Observer pattern which I'm using.
I have a presenter class (Model View Presenter) which implements the Observer pattern and it gets notified when certain events happens. I wrote generic Subject/Observer classes that any class can inherit from. The update method looks something like this:
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
. Now the expression (subject == myService_)
is no longer valid.
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? 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
Should an observer pattern Observer interface take a shared pointer? 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() {}
};
You can use shared_ptr
's get member, which returns the raw pointer that the shared_ptr
wraps:
subject == myService_.get()
In general I would not suggest to blindly convert all raw pointers to shared_ptr
s. 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.
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).
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.