如何确保调用派生的 class 方法?

How do I make sure I get the derived class method called?

我已经有一段时间没有用 C++ 做很多事情了。我正在尝试通过传入观察者 class 的派生 classes 并将它们存储在 vector<Observer> 中来实现可观察模式。我知道我传入的是派生的class对象,因为在registerObserver()方法中调用notify()方法调用的是派生的class方法。当我从向量中取出对象并调用通知方法时,我得到了基础 class 方法。

我很确定是对 push_back(observer) 的调用(或两者)将派生 class 的副本创建为基础 class 对象,或者 for(Observer o : observers) { 这就是问题的原因。

这里是感兴趣的代码:

基地class

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

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

派生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");
}

主题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();
    }
}

"main" (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);
}

如果你有一个vector<Observer>,当你存储一个DerivedObserver时,向量只将它存储为一个Observer,切片对象。如果要保留派生对象,则必须存储对象引用(指针)。当然,这意味着派生对象实际上必须保持活动状态才能稍后调用它。