2011-08-22 69 views
0

我正在尝试使用模板主题类实现观察者模式。观察者不需要(需要)知道主题类型,所以我为没有这种类型的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 *更改为int *时,它会编译OK。我假设模板主题和非模板接口有问题,但这不是gcc告诉我的,并且使用int *时似乎不是问题。

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

任何人都可以告诉我,我做错了什么或我怎么能从非模板观察者调用模板附加方法?

+0

您的'subject.cpp'应该包含'subject.h',非?而不是相反 - 为什么你在一个头文件中包含一个.cpp文件? –

+1

@Kerrek SB:因为'Subject'是一个类模板,并且类模板定义必须在实例化处可见(除非您使用导出的模板)。当然,用'.cpp'后缀内联头是不吉利的。 –

+0

@ phresnel:是的,当然。我对标题结构有些困惑...... –

回答

1

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

这意味着包含警卫将阻止观察者被看见。要解决它,而不是前向声明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_ 
0

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