我正在尝试使用模板主题类实现观察者模式。观察者不(需要)知道主题类型,因此我为没有这种类型的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)并不是我需要的。
有谁可以告诉我,我做错了什么或如何从非模板观察者调用模板化附加方法?
答案 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
,反之亦然。您需要使用转发声明来解决此问题。