尝试将观察者注册到模板主题类时编译错误

时间:2011-08-22 11:00:41

标签: c++ templates observer-pattern

我正在尝试使用模板主题类实现观察者模式。观察者不(需要)知道主题类型,因此我为没有这种类型的attach方法创建了一个接口。这是我的实施:

SubjectInterface.h

#ifndef SUBJECTINTERFACE_H_
#define SUBJECTINTERFACE_H_
#include <list>
#include "Observer.h"
// Template-independant interface for registering observers
class SubjectInterface
{
public:
  virtual void Attach(Observer*) = 0;
}; // class SubjectInterface
#endif // SUBJECTINTERFACE_H_

Subject.h

#ifndef SUBJECT_H_
#define SUBJECT_H_
#include <list>
#include "Observer.h"
#include "SubjectInterface.h"
template <class T>
class Subject : public SubjectInterface
{
public:
  Subject();
  ~Subject();
  void Attach(Observer*);
private:
  T                        mValue;
  std::list<Observer*> mObservers;
}; // class Subject
#include "Subject.cpp"
#endif // SUBJECT_H_

Subject.cpp

template <class T>
Subject<T>::Subject()
{
}
template <class T>
Subject<T>::~Subject()
{
}
template <class T>
void Subject<T>::Attach(Observer* test)
{
  mObservers.push_back(test);
}

Observer.h

#ifndef OBSERVER_H_
#define OBSERVER_H_
#include "SubjectInterface.h"
#include <iostream>
class Observer
{
public:
  Observer(SubjectInterface* Master);
  virtual ~Observer();
private:
  SubjectInterface* mMaster;
}; // class Observer
#endif // OBSERVER_H_

Observer.cpp

#include "Observer.h" // include header file
Observer::Observer(SubjectInterface* Master)
{
  Master->Attach(this);
}
Observer::~Observer()
{
}

当我使用gcc 4.3.4编译它时,我收到以下错误消息:

SubjectInterface.h:10: error: ‘Observer’ has not been declared

我不明白这一点,因为Observer仅包含在上面几行。当我将指针类型从Observer *更改为int *时,它编译好了。我假设模板主题和它的非模板接口存在问题,但这不是gcc告诉我的,并且在使用int *时似乎不是问题。

我搜索了模板/观察者,但我发现的(例如Implementing a Subject/Observer pattern with templates)并不是我需要的。

有谁可以告诉我,我做错了什么或如何从非模板观察者调用模板化附加方法?

2 个答案:

答案 0 :(得分:1)

你有一个循环包含链,SubjectInterface.h包含Observer.h,它反过来包括SubjectInterface.h。

这意味着包含防护将阻止Observer可见。要修改它而不是向前声明Observer。

// SubjectInterface.h
#ifndef SUBJECTINTERFACE_H_
#define SUBJECTINTERFACE_H_
#include <list>
class Observer; //Forward declaration
// Template-independant interface for registering observers
class SubjectInterface
{
public:
  virtual void Attach(Observer*) = 0;
}; // class SubjectInterface
#endif // SUBJECTINTERFACE_H_

答案 1 :(得分:0)

你有循环依赖; Observer.h包括SubjectInterface.h,反之亦然。您需要使用转发声明来解决此问题。