我有一个基础和一个派生类:
plugin.h
#ifndef PLUGIN_H
#define PLUGIN_H
// plugin states
#define PLUGIN_IDLE 0
class Plugin {
public:
Plugin();
~Plugin();
virtual void loop();
};
#endif
plugin.cpp
#include <Arduino.h>
#include "plugin.h"
Plugin::Plugin() {
}
Plugin::~Plugin(){
}
void Plugin::loop(){
Serial.println("Plugin::loop()");
}
派生类
class OneWirePlugin : public Plugin {
public:
OneWirePlugin(byte pin);
void loop();
};
OneWirePlugin::OneWirePlugin(byte pin) {
}
void OneWirePlugin::loop() {
Serial.println("OneWirePlugin::loop()");
}
我原以为调用派生实例的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()
允许调用派生实现的虚拟方法有什么问题,特别是在通过*Plugin
指针引用时?
答案 0 :(得分:7)
loop
必须声明为virtual
:
class Plugin {
// ...
virtual void loop();
此外,要使多态性起作用,您需要一个指针或引用:
Plugin* o = new OneWirePlugin(ONEWIRE_PIN);
o->loop();
// ...
delete o;
(在您的代码中,slicing出现,如评论部分中的Mat所示)
然后,考虑使用智能指针(如unique_ptr
或shared_ptr
)。
如果你正在使用C ++ 11,你还应该在子类中使用loop
说明符标记override
:
class OneWirePlugin : public Plugin {
// ...
void loop() override {
答案 1 :(得分:0)
在你的问题中 - 1.插件p = new Plugin(); 2.插件o = OneWirePlugin(ONEWIRE_PIN);
以下示例将有所帮助。
class Base { int x, y; };
class Derived : public Base { int z, w; };
int main()
{
Derived d;
Base b = d; // Object Slicing, z and w of d are sliced off
}
在IDE上运行 将派生类对象分配给基类对象时会发生对象切片,派生类对象的其他属性会被切除以形成基类对象。