我如何确保调用派生类方法?

时间:2017-12-29 19:59:02

标签: c++ inheritance object-slicing

自从我用c ++做了很多事以来,已经有一段时间了。我试图通过传入Observer类的派生类并将它们存储在notify()中来实现可观察模式。我知道我传入一个派生类对象,因为registerObserver()方法中对push_back(observer)方法的调用会调用派生类方法。当我从向量中获取对象并调用notify方法时,我得到了基类方法。

我很确定它是(或者两者)对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();
    }
}

主题课

//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);
}
&#34;主要&#34; (Ardunio)

import java.io.*;
import java.net.*;
public class AppChat {

    String[] list = { 
        "Take me ", 
        "the code", 
        "Hello from the other side", 
        "the man ",
        "what can we do?", 
        "that is all for today" 
        };

    void go() {
        try {
            ServerSocket serverSocket = new ServerSocket(53439);
            boolean t = true;
            while (true) {
                System.out.println("i am about to execute serverSocket");

1 个答案:

答案 0 :(得分:0)

如果您有vector<Observer>,则在存储DerivedObserver时,该向量仅将其存储为Observer,并对该对象进行切片。如果要保留派生对象,则必须存储对象引用(指针)。当然,这意味着派生对象实际上必须保持活着才能稍后调用。