Question

I'm trying to implement the observer pattern in C++. What I attempting to do is to declare an observer interface with a single pure virtual method: notify(), and then let the the observers implement/derive that interface. Additionally, I want to keep a vector of pointers to all the observer classes in the observed class, so that I can call notify() on each of them. Sadly I'm having some trouble with the vector of pointers.

This is the observer interface:

class LocationEstimateObserver {
public:
virtual void notify() = 0;
};

I have two different classes implementing this interface. Hence, both implement the notify() method.

Here my observed class:

class Simulator {
 public:
  Simulator();
  virtual ~Simulator();

  void registerListener(LocationEstimateObserver& observer){observers_.push_back(&observer); };
  void notifyObservers();

 private:

 std::vector<LocationEstimateObserver*> observers_;

};

And the observer class (implements the observer interface):

void InMapsEngine::startSimulation() {

Simulator sim();

sim.registerListener(*this);

}

And the Simulator.cpp file:

void Simulator::notifyObservers() {

  for (unsigned int i = 0; i < observers_.size(); i++) {

    observers_.at(i)->notify();

      }
 }

Now when I run the above code I get a segmentation fault. Could anyone of you point out what what I am doing wrong? I'm very new to C++.

EDIT: I just made a bizarre discovery: when I call observers_.size() it returns a very odd negative number, so the for loop fails. There lies the problem.

Was it helpful?

Solution

Why instead of adding instances of subclasses of LocationEstimateObserver, don't you have a vector of functions that will be notified when something will occur?:

Something like:

class Simulator {
 public:
  Simulator();
  virtual ~Simulator();

  void registerListener(const function<void()>& observer ) {observers_.push_back(observer); };
  void notifyObservers();

 private:

 std::vector<function<void()>> observers_;
};


void observer1()
{
}

int main()
 {
Simulator sim;

sim.registerListener(observer1);

}

And the Simulator.cpp file:

void Simulator::notifyObservers() {

  for (auto& observer : observers_)
      observer();

 }

OTHER TIPS

You keep a vector of pointers to objects that could have been deleted right after being registered. Make sure they are still there when you call Simulator::notifyObservers().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top