Ни базовая, ни производная виртуальная функция не называются должным образом
У меня есть этот базовый класс:
// 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());
}
Должен отображать 0
, Однако это отображает -64
, Даже если я переопределю f_focus()
метод на WakeUp
учебный класс. Если я удалю virtual
спецификатор от f_focus()
работает нормально, отображается 0
, но я не смогу получить доступ к производной реализации класса этого метода. Я хочу понять, что вызывает это странное поведение и что я могу сделать, чтобы избежать этого.
РЕДАКТИРОВАТЬ:
Функция работает нормально, если я вызываю ее из Gadget
Конструктор.
1 ответ
Вы режете свой WakeUp
объект.
По сути, у вас есть следующее:
Gadget g = WakeUp(...);
Этот код делает следующее:
- Построить
WakeUp
объект. - Вызов
Gadget(const Gadget& other)
с основанием изWakeUp
объект. - Уничтожить временный
WakeUp
объект, оставляя только копиюGadget
база.
Чтобы избежать этого, вам нужно создать массив указателей (лучше, если они умные указатели).
Gadget* gadgets[1] = { new WakeUp(&u8g) }; // If you choose this method, you need to call
// delete gadget[0] or you will leak memory.
Использование указателя правильно сохранит Gadget
а также WakeUp
экземпляры вместо того, чтобы отрезать их.
С умными указателями:
std::shared_ptr<Gadget> gadgets[1] = { std::make_shared<WakeUp>(&u8g) };