2013-03-12 52 views
0

我想创建一个抽象类,其他类可以基于arduino项目。但是,每当我调用一个基本虚拟的方法时,它就会调用基本实现。下面的代码。任何人都可以看到我做错了什么?Overriden虚拟方法不被调用

#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(); 
+2

也许你正在经历对象切片。 – chris 2013-03-12 04:09:34

+0

你是1)在派生类中定义函数和2)不切片,对吧?另外一个类不是抽象的,除非它至少有一个纯粹的虚拟成员函数,而你自己并不是。 – 2013-03-12 04:09:42

+0

您必须展示您的使用情况。如何创建类实例,如何将其转换为基类,以及如何调用该函数? – 2013-03-12 04:11:18

回答

2

你的代码:

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

object slicing(如@克里斯最初猜测)。对于Polymorphism的工作,你必须假装你的派生类是一个基类,通过将指针或引用作为基础,当它真的是Derived的地址时。 (因为派生实际上包含其中的基础)。

Derived myDerived; 
Base &myBaseRef = myDerived; 

myBaseRef.myVirtualFunction(); 

否则,你正在创建一个派生,并试图字节力为基本,并失去所有派生的字节。这不好! =)

问题是,你实际上不应该将转换成 Derived to a Base,只是访问Derived就好像它是一个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为您处理对象的生命周期,所以你不”你必须记得打电话'删除':

std::unique_ptr<Base> myBase; 

//Later... 
myBase = new Derived; 
myBase->myVirtualFunction(); 

//Automatically freed when the myBase smart pointer goes out of scope... 
+0

我*认为*有意义... 有没有一种好的方法来做到这一点,以便RTC_Base&RTC可以是一个全局变量(并没有设置为什么,直到setup()方法)?此外,是否有可能做到这一点,仍然有基地包含纯虚拟? – 2013-03-12 04:22:40

+0

我只是得到“错误:'RTC'声明为参考,但未初始化 ”当我尝试使其全局变为无立即初始化时 – 2013-03-12 04:24:10

+0

当然,请使用指针而不是引用。 RTC_Base * globalBase = NULL; 稍后:globalBase = new Derived; 只要确保您在globalBase上调用'delete',因为您正在动态分配内存。 ('删除'你所有的'新') – 2013-03-12 04:24:12

相关问题