dtg
dtg

Reputation: 1853

C++ and Qt: observer pattern error

I am trying to implement a simple observer pattern to update widgets with relevant info for a Car Model. I keep getting a rather perplexing error for the update method of my Observer pattern, where the compiler seems to fail to recognize the type of the parameter being passed. This is the header for Observer:

#include "Subject.h"

class Observer
{
public:

    virtual void update(Subject &car) = 0;
};

Subject header file:

#include <QList>

#include "Observer.h"

class Subject
{
protected:

    QList<Observer *> m_observers;

public:

    virtual void registerObserver(Observer &) = 0;
    virtual void removeObserver(Observer &) = 0;
    virtual void notifyObservers() = 0;
};

And the the implementation for the Subject (class Car inherits Subject interface):

//
// Subject interface implementation
//
void Car::registerObserver(Observer &observer)
{
    m_observers.append(&observer);
}

void Car::removeObserver(Observer &observer)
{
    int i = m_observers.indexOf(&observer);

    if (i >= 0)
        m_observers.removeAt(i);
}

void Car::notifyObservers()
{
    for(int i = 0; i < m_observers.size(); ++i)
        m_observers.at(i)->update(*this);
}

However, the compiler gives me an error at the notifyObservers method:

/home/dylan/Desktop/CarModel/Car.cpp:50: error: no matching function for call to ‘Observer::update(Subject&)’

 candidate is: /home/dylan/Desktop/CarModel/Observer.h:11: virtual void Observer::update(int&)

Uhhhh.... what?? As you can see, the compiler seems to think that the parameter for update is a reference to an int. Is this because my Observer header is abstract? I haven't written an implementation for it yet, so perhaps this is why?

Upvotes: 0

Views: 804

Answers (2)

K-ballo
K-ballo

Reputation: 81379

You have a cyclic include dependency. Observer includes Subject and Subject includes Observer. Now the header guards will take care of preventing infinite inclusion, but still one of the headers has to be included first, they cannot be included both at the same time. It happens that the first one to be included is Observer, and at that point Subject is not yet declared.

Luckily, you don't seem to need any of those includes. You can replace them with a forward declaration:

class Subject;

class Observer
{
public:

    virtual void update(Subject &car) = 0;
};

Upvotes: 2

juanchopanza
juanchopanza

Reputation: 227478

You have a circular dependency between Observer and Subject. You can avoid it by forward-declaring Subject in Observer.h instead of including Subject.h:

class Subject; // forward declaration

class Observer {
  ...
};

And do the same in the Subject.h:

class Observer; // forward declaration
class Subject {
  ...
};

Upvotes: 3

Related Questions