如何确保调用派生的 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
,切片对象。如果要保留派生对象,则必须存储对象引用(指针)。当然,这意味着派生对象实际上必须保持活动状态才能稍后调用它。
我已经有一段时间没有用 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
,切片对象。如果要保留派生对象,则必须存储对象引用(指针)。当然,这意味着派生对象实际上必须保持活动状态才能稍后调用它。