2016-10-05 3 views
0

OK、もう一度試してみます。私は経験豊富なC++プログラマーではないので、何かにちょっとした助けが必要です。コンパイルされない、非常に単純なコードがあります。私が知りたいのは、コードがコンパイルされるようにgetData()とsize()メソッドを定義できるかどうかです。私が手にエラーがある:スーパークラスでconstメソッドを使用するにはどうすればいいですか?

エラーC2662: 'いるIContainer ::のgetData': 'のconstいる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

私は非常に割り当てを置くことを控えるをお勧めしますスーパークラス(または親クラス)の演算子。

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

こんにちはトーマス、私に明確な答えを書く時間をとってくれてありがとう。私はあなたの点を感謝します。私の防衛では、代入演算子はサブクラスにデータとサイズのポインタを問い合わせるだけです。これらのデータを1バイトずつ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関数である、あなたは、const参照であるTのためにそれを呼び出すことが許可されていません。これは割り当てとは関係ありません。

この作業を行うには多くの方法があります。

  • getData()
  • のためのconstのオーバーロードを提供const参照
  • に無用getData()を呼び出すことはありませんが、専用のconst通知コールバック
  • を提供します
  • とにかく溝割り当て(とにかく多態的なクラス階層の中では本当に悪い考えです)
0

OK、私はそれをコンパイルしました - 私は "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; 
}; 
関連する問題