2016-10-05 55 views
0

OK使用const的方法,我會嘗試這一個更多的時間。我不是一個有經驗的C++程序員,所以我只需要一些幫助。這是一些非常簡單的代碼,不會編譯。我想知道的是,是否可以定義getData()和size()方法,以便代碼能夠被編譯?我得到的錯誤是:我怎麼在超

錯誤C2662:「的IContainer ::的getData」:不能從「常量的IContainer」轉換「這個」指針「的IContainer &」

#include <functional> 
#include <stdint.h> 

class iContainer { 
public: 
    virtual   const int  size() = 0; 
    virtual   const uint8_t * getData() = 0; 
    void operator=(const iContainer &iC) { saveToEEPROM(iC.getData(), iC.size()); } 

private: 
    void saveToEEPROM(uint8_t *pData, int size) { 
     // Save the data to EEPROM. 
    } 
}; 


class Timer : public iContainer { 
public: 
    Timer() { 
     pData.myData = 0; 
    }; 
    Timer(uint8_t startHour) { 
     pData.myData = startHour; 
    } 
    virtual const int size() { return sizeof(pData); } 
    virtual const uint8_t *getData() { return (const uint8_t *)&pData; }; 
private: 
    struct { 
     uint8_t myData; 
    } pData; 

} 
+1

/OT:提示:'的std :: function'是非常沉重的性能(在編譯和運行)。除非絕對需要(不要),否則不應使用它。 – Rakete1111

+1

請提供確切的一行,這會使編譯器不快樂和完整的編譯器消息。你的代碼片段似乎並沒有顯示出來。 – SergeyA

+1

@ Rakete1111,並不比遍佈此代碼的虛擬函數(相同級別)差。 OP似乎並不關心性能。 – SergeyA

回答

2

我強烈的將分配建議制止超類(或父類)中的操作符。

這裏有兩個主要問題:1)切片和2)多態性。

多態性
在一個超類配售賦值運算符允許:

class Fruit; 
class Apple : public Fruit; 
class Orange : public Fruit; 
void Blender(Fruit * p_fruit) 
(
    Apple a; 
    Orange o; 
    Fruit * ptr_o = &o; 
    Fruit * ptr_a = &a; 
    // This is syntactically allowed, but may not make sense. 
    *p_fruit = *ptr_o; 
    *p_fruit = *ptr_a; 
    // This is also allowed: 
    *ptr_o = *ptr_a; // Assigning apples to oranges 
} 

超類不能對孩子班級任何保證(合同)。

切片
當分配部件是在超類成員的唯一保證(的,形式)。這是一種切片的形式;只有超類成員被複制(分配)。

人們可以創建一個虛擬的分配方法,但同樣,孩子不知道,如果該參數是一個表姐或兄弟姐妹(見上文多態性)。

摘要 請勿將賦值運算符放置在超類或父類中。如果您有超數據成員,創建一個超類的成員分配保護方法。不要推斷任何有關兒童課程的內容。

+0

嗨托馬斯,謝謝你花時間給我寫一個明確的答案。我讚賞你的觀點。在我的辯護中,這個想法是,賦值操作符會簡單地向子類查詢指向其數據的指針和大小;然後將這些數據逐字節寫入EEPROM。那有意義嗎? – Greycon

+0

我在嵌入式系統上工作,我沒有看到定時器和EEPROM之間的任何連接。如果您想使用一個類來建模EEPROM,請將其視爲「uint8_t」或「uint16_t」的數組。問題是許多不同類型的數據可以存儲在EEPROM中,並將其作爲容器意味着您必須處理多種數據類型,這在C++中是一種痛苦。 –

1

的錯誤信息是非常明確的。

prog.cpp:24:74: error: passing 'const iContainer' as 'this' argument discards qualifiers [-fpermissive] 
    void operator= (const iContainer &T) { this->deSerialize(T.getData()); }; 

getData是一個非const函數,你不能叫它對於T這是一個常量引用。這與分配無關。

有許多方法來完成這項工作:在一個const引用

  • 不叫無用getData()
  • 提供getData()
  • 一個const過載提供專用const的通知回調
  • 溝分配共(它在一個多態類層次結構一個非常糟糕的想法)
0

好的,我把它編譯 - 我需要了解更多關於「const」的語義。我明白這是一個人爲的例子。

的#include 的#include

class iContainer { 
public: 
    virtual   const int  size() const = 0; 
    virtual   const uint8_t * getData() const = 0; 
    void operator=(const iContainer &iC) { saveToEEPROM(iC.getData(), iC.size()); } 

private: 
    void saveToEEPROM(const uint8_t *pData, int size) { 
     // Save the data to EEPROM. 
    } 
}; 


class Timer : public iContainer { 
public: 
    Timer() { 
     pData.myData = 0; 
    }; 
    Timer(uint8_t startHour) { 
     pData.myData = startHour; 
    } 
    virtual const int size() { return sizeof(pData); } 
    virtual const uint8_t *getData() { return (const uint8_t *)&pData; }; 
private: 
    struct { 
     uint8_t myData; 
    } pData; 
};