我尝试使用https://sourcemaking.com/design_patterns/observer/cpp/3
中提供的Observer模式代码Observer.h
#ifndef OBSERVER_H_
#define OBSERVER_H_
namespace my {
class Subject;
//template <class T>
class Observer {
Subject*model;
int denom;
public:
Observer(Subject*mod, int div);
virtual void update() = 0;
virtual ~Observer();
protected:
Subject*getSubject();
int getDivisor();
};
} /* namespace my */
#endif /* OBSERVER_H_ */
Observer.cpp
#include "Observer.h"
//#include "Subject.h"
namespace my {
Observer::Observer(Subject*mod, int div)
{
model = mod;
denom = div;
// 4. Observers register themselves with the Subject
model->attach(this);
}
Subject* Observer::getSubject()
{
return model;
}
int Observer::getDivisor()
{
return denom;
}
Observer::~Observer() {
// TODO Auto-generated destructor stub
}
} /* namespace my */
DivObserver.h
#ifndef DIVOBSERVER_H_
#define DIVOBSERVER_H_
#include <iostream>
#include "Observer.h"
using namespace std;
namespace my {
class DivObserver : public Observer
{
public:
DivObserver(Subject*mod, int div);
void update();
virtual ~DivObserver();
};
} /* namespace my */
#endif /* DIVOBSERVER_H_ */
DivObserver.cpp
#include "DivObserver.h"
namespace my {
DivObserver::DivObserver(Subject*mod, int div): Observer(mod, div){
// TODO Auto-generated constructor stub
}
void DivObserver::update()
{
// 6. "Pull" information of interest
int v = getSubject()->getVal(), d = getDivisor();
cout << v << " div " << d << " is " << v / d << '\n';
}
DivObserver::~DivObserver() {
// TODO Auto-generated destructor stub
}
} /* namespace my */
Subject.h
#ifndef SUBJECT_H_
#define SUBJECT_H_
#include<vector>
using namespace std;
namespace my {
//template <class T>
class Subject {
vector <class Observer*> views; // 3. Coupled only to "interface"
int value;
public:
Subject();
virtual ~Subject();
void attach(Observer*obs);
void setVal(int val);
int getVal();
void notify();
};
} /* namespace my */
#endif /* SUBJECT_H_ */
Subject.cpp
#include "Subject.h"
namespace my {
Subject::Subject() {
// TODO Auto-generated constructor stub
}
void Subject::attach(Observer*obs)
{
views.push_back(obs);
}
void Subject::setVal(int val)
{
value = val;
notify();
}
int Subject::getVal()
{
return value;
}
void Subject::notify()
{
// 5. Publisher broadcasts
for (int i = 0; i < views.size(); i++)
views[i]->update();
}
Subject::~Subject() {
// TODO Auto-generated destructor stub
}
} /* namespace my */
Test.cc
#include <iostream>
#include <vector>
#include "Subject.h"
#include "DivObserver.h"
using namespace std;
using namespace my;
int main() {
Subject subj;
DivObserver divObs1(&subj, 4); // 7. Client configures the number and
DivObserver divObs2(&subj, 3); // type of Observers
subj.setVal(14);
}
它抱怨循环引用。如果我插入课程主题;它说含糊不清的主题。请帮我解决这个问题。
答案 0 :(得分:0)
解决此问题的最简单方法是在一个文件中声明和定义observer和observable。这意味着
Subject.h
#ifndef SUBJECT_H_
#define SUBJECT_H_
#include<vector>
namespace my {
class Subject;
//template <class T>
class Observer {
Subject*model;
int denom;
public:
Observer(Subject*mod, int div);
virtual void update() = 0;
virtual ~Observer();
protected:
Subject*getSubject();
int getDivisor();
};
//template <class T>
class Subject {
std::vector <Observer*> views; // 3. Coupled only to "interface"
int value;
public:
Subject();
virtual ~Subject();
void attach(Observer*obs);
void setVal(int val);
int getVal();
void notify();
};
} /* namespace my */
#endif
Subject.cpp
#include "Subject.h"
namespace my {
DivObserver::DivObserver(Subject*mod, int div): Observer(mod, div){
// TODO Auto-generated constructor stub
}
void DivObserver::update()
{
// 6. "Pull" information of interest
int v = getSubject()->getVal(), d = getDivisor();
cout << v << " div " << d << " is " << v / d << '\n';
}
DivObserver::~DivObserver() {
// TODO Auto-generated destructor stub
}
Subject::Subject() {
// TODO Auto-generated constructor stub
}
void Subject::attach(Observer*obs)
{
views.push_back(obs);
}
void Subject::setVal(int val)
{
value = val;
notify();
}
int Subject::getVal()
{
return value;
}
void Subject::notify()
{
// 5. Publisher broadcasts
for (int i = 0; i < views.size(); i++)
views[i]->update();
}
Subject::~Subject() {
// TODO Auto-generated destructor stub
}
}
更难和正确的方法是声明抽象接口
IObserver
和IObservable
它定义了Observer和Observable的通用接口,而不是从它们派生我们的类。
Observer.h
#ifndef __IOBSERVER_H__
#define __IOBSERVER_H__
class IObserver
{
public:
void update() void = 0;
};
#endif /* __IOBSERVER_H__ */
Observable.h
#ifndef __IOBSERVERVABLE_H__
#define __IOBSERVERVABLE_H__
#include "Observer.h"
class IObservable
{
public:
void attach(IObserver* pObserver) void = 0;
};
#endif /* __IOBSERVERVABLE_H__ */
然后派生孩子
class Subject: public IObservable
{
};
class Observer: public IObserver
{
};