2017-12-29 15 views
0

私はC++で多くをして以来、しばらくしています。 Observerクラスの派生クラスを渡して、vector<Observer>に格納することによって、観測可能なパターンを実装しようとしています。 registerObserver()メソッドのnotify()メソッドへの呼び出しが派生クラスメソッドを呼び出すため、派生クラスオブジェクトを渡していることがわかります。私がベクトルからオブジェクトを取得し、notifyメソッドを呼び出すと、私は基本クラスのメソッドを取得します。派生クラスのメソッドが呼び出されるようにするにはどうすればよいですか?

基本クラスオブジェクトとして派生クラスのコピーを作成しているpush_back(observer)を呼び出すか、問題の原因であるfor(Observer o : observers) {を呼び出すのがどちらか(またはその両方)であることは間違いありません。

基底クラス

// Observer.h 
class Observer 
{ 
    public: 
    virtual void notify(); 
}; 

// Observer.cpp 
void Observer::notify() 
{ 
    Serial.println("got a notification in base class"); 
} 

派生クラス

// DatabaseUpdater.h (derived class) 
class DatabaseUpdater : public Observer 
{ 
    public: 
    void notify() override; 
}; 

// DatabaseUpdater.cpp 
void DatabaseUpdater::notify() 
{ 
    Serial.println("got a notification in database class"); 
} 

対象クラス

// HwMonitor.h (subject class) 
class HwMonitor 
{ 

    public: 
    void registerObserver(Observer& observer); 
    void event(); 

    private: 
    std::vector<Observer> observers; 
}; 

//HwMonitor.cpp 
void HwMonitor::registerObserver(Observer &observer) 
{ 
    Serial.println("adding observer"); 
    observer.notify(); 
    observers.push_back(observer); 
} 

void HwMonitor::event() 
{ 
    Serial.println("event"); 
    for(Observer o : observers) { 
     o.notify(); 
    } 
} 

"メイン"(:ここ

は、関心のあるコードでありますArdunio)

//app.ino 
DatabaseUpdater o; 
HwMonitor esp; 

void setup() 
{ 
    Serial.begin(115200); 
    delay(2000); 
    Serial.println("registering observer"); 
    esp.registerObserver(o); 
} 

void loop() 
{ 
    Serial.println("calling an event"); 
    esp.event(); 
    delay(1000); 
} 
+5

'HwMonitor'のあなたのベクトルは多形性に必要な参照やポインタではなく*オブジェクト*を格納します。 [オブジェクトのスライス*について読む](http://stackoverflow.com/questions/274626/what-is-object-slicing)をご覧ください。 –

+0

「奇妙に繰り返されるテンプレートパターン」を参照してください。 https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern –

+0

@Someprogrammerdudeありがとう、私はこれが起こっていたと仮定しましたが、どこではわからなかったのです。 – nPn

答えて

0

あなたがDerivedObserverを保存するときに、vector<Observer>を持っている場合は、ベクターは、オブジェクトのみをスライスし、Observerとしてそれを格納します。派生オブジェクトを保持する場合は、オブジェクト参照(ポインタ)を格納する必要があります。もちろん、それは、後で呼び出されるためには、派生オブジェクトが実際には生き残っていなければならないということです。

関連する問題