【问题标题】:C++ and Qt: observer pattern errorC++ 和 Qt:观察者模式错误
【发布时间】:2012-06-15 15:45:28
【问题描述】:

我正在尝试实现一个简单的观察者模式,以使用汽车模型的相关信息更新小部件。我的观察者模式的更新方法不断收到一个相当令人困惑的错误,编译器似乎无法识别所传递参数的类型。这是 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;
};

Subject 的实现(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 标头是抽象的吗?我还没有为它写一个实现,所以也许这就是为什么?

【问题讨论】:

  • 是否在您定义 Observer 时声明了 Subject
  • 是的。我忘记为上面的 Observer 标头添加包含,尽管它已经在我的代码中。
  • 哪里不是?它位于 Observer 标头中。我只是忘记在此处添加它,但它在我的代码中。
  • 有点旁白,但您确实知道 Qt 的信号和插槽,对吧?这使得在不重新发明轮子的情况下实现观察者模式变得非常简单。
  • 是的,现在我想起来了,用你描述的信号和插槽来实现它可能会更容易。

标签: c++ qt observer-pattern


【解决方案1】:

您有一个循环包含依赖项。 Observer 包括 SubjectSubject 包括 Observer。现在标题保护将负责防止无限包含,但仍然必须首先包含一个标题,它们不能同时包含。碰巧第一个被包含的是Observer,而此时Subject 尚未声明。

幸运的是,您似乎不需要任何这些内容。您可以将它们替换为前向声明:

class Subject;

class Observer
{
public:

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

【讨论】:

    【解决方案2】:

    ObserverSubject 之间存在循环依赖关系。您可以通过在 Observer.h 中前向声明 Subject 而不是包含 Subject.h 来避免它:

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

    并且在Subject.h中做同样的事情:

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

    【讨论】:

    • 我现在看到了。那对我来说是一个相当愚蠢的错误。
    猜你喜欢
    • 2012-02-15
    • 2021-11-22
    • 2016-02-20
    • 2023-04-10
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2013-12-30
    • 2011-05-15
    相关资源
    最近更新 更多