Arduino 未正确调用基虚函数或派生虚函数
我有一个基本类:Arduino 未正确调用基虚函数或派生虚函数,arduino,arduino-c++,Arduino,Arduino C++,我有一个基本类: // put the display in a macro on a .h file for less headache. class Gadget { protected: int x, y; U8GLIB * u8g; virtual int f_focus() {return 0;}; virtual int f_blur() {return 0;}; virtual void f_draw() {};
// put the display in a macro on a .h file for less headache.
class Gadget {
protected:
int x, y;
U8GLIB * u8g;
virtual int f_focus() {return 0;};
virtual int f_blur() {return 0;};
virtual void f_draw() {};
virtual void f_select() {};
public:
Gadget(U8GLIB * u8g, int x, int y) :
u8g(u8g),
x(x),
y(y)
{
Serial.println(F("Gadget(U8GLIB * u8g, int x, int y)"));
};
Gadget() {
Serial.println(F("Gadget()"));
};
int focus(){return f_focus();};
int blur(){return f_blur();};
void draw(){f_draw();};
void operator()(){f_select();};
};
这个派生类:
class WakeUp :
public Gadget
{
public:
WakeUp(U8GLIB * u8g) :
Gadget(u8g, 0, 0)
{
Serial.println(F("WakeUp(U8GLIB * u8g)"));
};
};
然后我在数组中实例化WakeUp类,如下所示:
Gadget gadgets[1] = {
WakeUp(&u8g)
};
void focus() {
Serial.println(gadgets[0].focus());
}
然后,我尝试如下方式访问此成员:
Gadget gadgets[1] = {
WakeUp(&u8g)
};
void focus() {
Serial.println(gadgets[0].focus());
}
它应该显示0
。但是,它正在显示-64
。即使我重写了WakeUp
类上的f_focus()
方法。如果我从f_focus()
中删除virtual
说明符,它可以正常工作,显示0
,但我将无法访问此方法的派生类实现。
我想了解是什么导致了这种奇怪的行为,我能做些什么来避免它
编辑:
如果我从
Gadget
构造函数调用该函数,该函数运行良好。您正在切片唤醒对象
您基本上有以下几点:
Gadget g = WakeUp(...);
此代码的作用如下:
Gadget g = WakeUp(...);
构造一个唤醒对象
使用唤醒
对象中的基址调用小工具(const Gadget&other)
销毁临时唤醒
对象,只留下小工具
库的副本
为了避免这种情况,您需要创建一个指针数组(如果它们是智能指针,这会更好)
使用指针将正确保留小工具
和唤醒
实例,而不是将它们切掉
使用智能指针:
std::shared_ptr<Gadget> gadgets[1] = { std::make_shared<WakeUp>(&u8g) };
std::shared_ptr gadgets[1]={std::make_shared(&u8g)};
您正在切片唤醒对象
您基本上有以下几点:
Gadget g = WakeUp(...);
此代码的作用如下:
Gadget g = WakeUp(...);
构造一个唤醒对象
使用唤醒
对象中的基址调用小工具(const Gadget&other)
销毁临时唤醒
对象,只留下小工具
库的副本
为了避免这种情况,您需要创建一个指针数组(如果它们是智能指针,这会更好)
使用指针将正确保留小工具
和唤醒
实例,而不是将它们切掉
使用智能指针:
std::shared_ptr<Gadget> gadgets[1] = { std::make_shared<WakeUp>(&u8g) };
std::shared_ptr gadgets[1]={std::make_shared(&u8g)};
在将返回值传递给串行.println
之前,是否必须将其转换为字符串?否。它接受整数值。小工具
s数组包含的是小工具
s,而不是小部件。如果要存储从Gadget
派生的类的实例,需要一个std::unique_ptr
s数组。我在arduino上没有stdlib。因此,我的小工具必须存储在一个数组中。Serial.println也接受整数。文件对此很清楚@量子物理学家虽然我感谢你的耐心和关于物体切片的传统信息,这是我直到今天才知道的,但是你在关于Serial.println的建议中遗漏了一些重要信息。它是一个arduino核心函数,在串行端口上打印它。它接受String(不是std::String,因为arduino不支持stdlib)、integer、float和char*。在将返回值传递到Serial.println
之前,是否必须将其转换为String?否。它接受整数值。Gadget
s数组包含Gadget
s,而不是小部件。如果要存储从Gadget
派生的类的实例,需要一个std::unique_ptr
s数组。我在arduino上没有stdlib。因此,我的小工具必须存储在一个数组中。Serial.println也接受整数。文件对此很清楚@量子物理学家虽然我感谢你的耐心和关于物体切片的传统信息,这是我直到今天才知道的,但是你在关于Serial.println的建议中遗漏了一些重要信息。它是一个arduino核心函数,在串行端口上打印它。它接受String(不是std::String,因为arduino不支持stdlib)、integer、float和char*。我不能使用智能指针,因为我没有stdlib。但我将尝试使用普通指针或接口类。谢谢。@luiz写一篇notstd::unique_ptr
既短又值得。我会试试看,因为我没有stdlib,所以我不能使用智能指针。但我将尝试使用普通指针或接口类。谢谢。@luiz写一篇notstd::unique_ptr
既短又值得。我会试试看