为什么没有调用子类的虚函数

and*_*dig -4 c++ arduino

我有一个基类和派生类:

plugin.h

#ifndef PLUGIN_H
#define PLUGIN_H

// plugin states
#define PLUGIN_IDLE 0

class Plugin {
public:
  Plugin();
  ~Plugin();

  virtual void loop();
};

#endif
Run Code Online (Sandbox Code Playgroud)

plugin.cpp

#include <Arduino.h>
#include "plugin.h"

Plugin::Plugin() {
}

Plugin::~Plugin(){
}

void Plugin::loop(){
  Serial.println("Plugin::loop()");
}
Run Code Online (Sandbox Code Playgroud)

派生类

class OneWirePlugin : public Plugin {
public:
  OneWirePlugin(byte pin);
  void loop();
};

OneWirePlugin::OneWirePlugin(byte pin) {
}

void OneWirePlugin::loop() {
  Serial.println("OneWirePlugin::loop()");
}
Run Code Online (Sandbox Code Playgroud)

我期待调用派生实例的loop()方法将执行OneWirePlugin::loop().

但是,这只发生在我在派生类上下文中调用它时:

Plugin p = Plugin();
Plugin o = OneWirePlugin(ONEWIRE_PIN);
OneWirePlugin q = OneWirePlugin(ONEWIRE_PIN);
p.loop(); // Plugin::loop()
o.loop(); // Plugin::loop()
q.loop(); // OneWirePlugin::loop()
Run Code Online (Sandbox Code Playgroud)

我的虚方法有什么问题可以调用派生的实现,特别是在通过*Plugin指针引用时?

Bar*_*zKP 7

loop必须声明为virtual:

class Plugin {

// ...

virtual void loop();
Run Code Online (Sandbox Code Playgroud)

此外,要使多态性起作用,您需要一个指针或引用:

Plugin* o = new OneWirePlugin(ONEWIRE_PIN);
o->loop();

// ...

delete o;
Run Code Online (Sandbox Code Playgroud)

(在您的代码中,切片发生,如评论部分中的Mat所示)

然后,考虑使用智能指针(如unique_ptrshared_ptr).


如果您使用的是C++ 11,还应该loop使用override子类中的说明符进行标记:

class OneWirePlugin : public Plugin {

// ...

void loop() override { 
Run Code Online (Sandbox Code Playgroud)