我正在尝试实现一个简单的观察者模式来更新具有汽车模型相关信息的小部件。对于我的Observer模式的更新方法,我一直遇到一个相当令人困惑的错误,其中编译器似乎无法识别传递的参数的类型。这是Observer的标题:
#include "Subject.h"
class Observer
{
public:
virtual void update(Subject &car) = 0;
};
主题标题文件:
#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;
};
主题的实现(Car继承Subject主题接口):
//
// 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);
}
但是,编译器在notifyObservers方法中给出了一个错误:
/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&)
呃......什么?如您所见,编译器似乎认为update的参数是对int的引用。这是因为我的Observer标题是抽象的吗?我还没有为它编写实现,所以也许这就是为什么?
答案 0 :(得分:3)
Observer
和Subject
之间存在循环依赖关系。您可以通过在Subject
中向前声明Observer.h
而不是包含Subject.h
来避免它:
class Subject; // forward declaration
class Observer {
...
};
在Subject.h
:
class Observer; // forward declaration
class Subject {
...
};
答案 1 :(得分:2)
您有循环包含依赖项。 Observer
包括Subject
,Subject
包括Observer
。现在标题保护将负责防止无限包含,但仍然必须首先包括其中一个标题,它们不能同时包含在内。碰巧要包含的第一个是Observer
,并且此时尚未声明Subject
。
幸运的是,您似乎不需要任何这些包含。您可以使用前向声明替换它们:
class Subject;
class Observer
{
public:
virtual void update(Subject &car) = 0;
};