未调用被重写的虚方法

Overriden Virtual methods not being called

本文关键字:方法 重写 调用      更新时间:2023-10-16

我试图创建一个抽象类,其他一些类可以基于arduino项目。但是,每当我调用一个在基中是虚的方法时,它只会调用基实现。下面的代码。有人能看出我哪里做错了吗?

#define RTCBASE 0
class RTC_Base {
public:
  virtual uint8_t begin(void){ return 0; };
  virtual void adjust(const DateTime& dt){};
  virtual DateTime now(){ return DateTime(); };
  virtual int Type(){ return RTCBASE; };
};
////////////////////////////////////////////////////////////////////////////////
// RTC based on the DS1307 chip connected via I2C and the Wire library
#define DS1307 1
class RTC_DS1307 : public RTC_Base 
{
public:
  virtual int Type(){ 
    return DS1307; 
  }
  uint8_t begin(void);
  void adjust(const DateTime& dt);
  uint8_t isrunning(void);
  DateTime now();
  uint8_t readMemory(uint8_t offset, uint8_t* data, uint8_t length);
  uint8_t writeMemory(uint8_t offset, uint8_t* data, uint8_t length);

};
///In Code
RTC_Base RTC = RTC_DS1307();
DateTime dt = RTC.now();
//The above call just returns a blank DateTime();

代码:

RTC_Base RTC = RTC_DS1307();
DateTime dt = RTC.now(); //The above call just returns a blank DateTime();

这就是对象切片(正如@chris最初猜测的那样)。要使多态性起作用,您必须假装派生类是基类,将指针或引用视为基类,而实际上它是派生类的地址。(因为派生类实际上包含了基类)。

Derived myDerived;
Base &myBaseRef = myDerived;
myBaseRef.myVirtualFunction();

否则,您正在创建派生类,并试图将字节强制转换为Base类,并丢失派生类的所有字节。这可不好!=)

关键是,您实际上不应该派生类转换为基类,而应该像访问基类一样访问派生类。如果将其转换为基数,则就是基数。并且你的基类返回一个空的DateTime。 对于动态分配的内存,您可以这样做:
Base *myBase = nullptr; //Or 'NULL' if you aren't using C++11
myBase = new Derived;
myBase->myVirtualFunction(); //Dereference the myBase pointer and call the function.
delete myBase; //Free the memory when you are finished.

如果你使用的是c++ 11,你可以让std::unique_ptr为你处理对象的生命周期,这样你就不必记得调用'delete':

std::unique_ptr<Base> myBase;
//Later...
myBase = new Derived;
myBase->myVirtualFunction();
//Automatically freed when the myBase smart pointer goes out of scope...