0

私は解決するために次の問題を与えています。任意のデータ型 (プリミティブ型またはユーザー型) を受け入れることができるように、ジェネリック サブジェクト クラス (オブザーバー パターンを参照) を作成します。登録、削除、および通知機能もカスタマイズ可能である必要があります。例として、データ型「int」でオブザーバーに通知する WeatherStation クラスがあります。オブザーバーの登録と削除に関する DB エントリを作成します。

もう 1 つの例 (図示されていません) は、証券取引所の相場でオブザーバーに通知する 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)'
4

1 に答える 1

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を処理するのObservorWeatherStationの責任であり、センサーなどからデータを取得するのは の責任です。

于 2015-07-07T17:15:42.840 に答える