0

我有这个基类:

// 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删除说明符可以正常工作,正在显示,但我将无法访问此方法的派生类实现。我想了解导致这种奇怪行为的原因以及我能做些什么来避免它。virtualf_focus()0

编辑:

如果我从Gadget构造函数调用它,该函数运行良好。

4

1 回答 1

2

你正在切割你的WakeUp对象。

你基本上有以下几点:

Gadget g = WakeUp(...);

这段代码的作用如下:

  1. 构造一个WakeUp对象。
  2. Gadget(const Gadget& other)WakeUp对象调用基地。
  3. 销毁临时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.

使用指针将正确地保留GadgetandWakeUp实例,而不是将它们切掉。

使用智能指针:

std::shared_ptr<Gadget> gadgets[1] = { std::make_shared<WakeUp>(&u8g) };
于 2017-09-18T15:04:58.427 回答