覆盖未调用的虚方法

时间:2013-03-12 04:08:29

标签: c++ inheritance arduino abstract-class

我正在尝试创建一个抽象类,其他一些类可以基于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();

1 个答案:

答案 0 :(得分:2)

你有代码:

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

那是object slicing(正如@chris最初猜测的那样)。要使Polymorphism起作用,当它确实是Derived的地址时,你必须通过将指针或引用视为Base来假装派生类是基类。 (因为Derived实际上包含其中的Base)。

Derived myDerived;
Base &myBaseRef = myDerived;

myBaseRef.myVirtualFunction();

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

重点是,您实际上不应该将转换 Derived转换为Base,只需访问Derived,就像它是Base一样。如果将其转换为Base,则 是一个基础。并且您的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...