2011-08-22 7 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_ 

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

나는이가 GCC 4.3.4를 사용하여 컴파일 Observer.cpp, 나는 다음과 같은 얻을 오류 메시지 :

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에는 SubjectInterface.h가 차례로 포함 된 Observer.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_ 
0

순환 종속성이 있습니다. Observer.h에는 SubjectInterface.h이 포함되며 그 반대의 경우도 마찬가지입니다. 너는 앞으로 선언로 이것을 끊을 필요가있을 것이다.

관련 문제