2013-03-12 50 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

相關問題