我一直在解决以下问题。创建一个通用的Subject类(指Observor Pattern),使它可以接受任何数据类型(原始或用户类型)。寄存器,删除和通知功能也需要定制。 例如,我们有一个WeatherStation类,它通知数据类型为'int'的观察者。它在注册和删除观察者时进行数据库输入。
另一个例子(未示出)是BroadcastHandler,它通知证券交易所股票交易所报价。它在注册和删除观察者时输入文件。
我编写了以下代码来实现它。
#include <iostream>
#include <set>
template <class T>
class Observor
{
public :
virtual void update(const T& t) = 0;
virtual ~Observor(){}
};
template<class T>
class Subject
{
public :
virtual void registerObservor(Observor<T>* obv) = 0;
virtual void removeObservor(Observor<T>* obv) = 0;
virtual void notifyObservors(T t);
virtual ~Subject(){}
};
template<class T>
class WeatherStation : public Subject<T>
{
public :
void registerObservor(Observor<T>* obv)
{
_observors.insert(obv);
//Make DB Entry
}
void removeObservor(Observor<T>* obv)
{
if(_observors.find(obv) != _observors.end())
{
_observors.erase(obv);
//Make DB Entry
}
}
void notifyObservors(T t)
{
for(auto itr = _observors.begin(),
itrEnd = _observors.end(); itr != itrEnd; ++itr)
{
(*itr)->update(t);
}
}
private :
std::set< Observor<T>* > _observors;
};
int main()
{
WeatherStation<int> wStation;
}
我从链接器
收到以下错误observor_pattern.o:observor_pattern.cpp:(.rdata$_ZTV7SubjectIiE[__ZTV7SubjectIiE]+0x10)||undefined reference to `Subject<int>::notifyObservors(int)'
答案 0 :(得分:0)
确实(正如链接器告诉您的那样)您没有Subject<T>::notifyObservors(T)
的定义,并且您没有将其声明为=0
。这是故意的吗?我认为正确的代码可能是
template<class T>
class Subject
{
public :
virtual void registerObservor(Observor<T>* obv) = 0;
virtual void removeObservor(Observor<T>* obv) = 0;
virtual void notifyObservors(T t) = 0;
// ^^^
virtual ~Subject(){}
};
虽然更好的方法是在Subject
中使用所有观察者处理代码,而不是WeatherStation
,因为这似乎是Subject
类的全部内容。处理Subject
是Observor
的责任,而WeatherStation
的责任应该是从传感器等处获取数据。