Общий предметный класс Observor Pattern

Я дал следующую проблему для решения. Создайте универсальный класс Subject (ссылающийся на шаблон Observor) так, чтобы он мог принимать любой тип данных (примитивный или пользовательский тип). Функции регистрации, удаления и уведомления также должны быть настраиваемыми. Например, у нас есть класс 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)'

1 ответ

На самом деле (как говорит вам компоновщик) у вас нет определения 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ответственность должна состоять в том, чтобы получать данные с датчиков и т. д.

Другие вопросы по тегам