我如何在超类

时间:2016-10-05 15:12:23

标签: c++ const

好的,我要再试一次。我不是一个经验丰富的C ++程序员,所以我只需要一些帮助。这是一些非常简单的代码,无法编译。我想知道的是,是否可以定义getData()和size()方法,以便代码编译?我得到的错误是:

错误C2662:'iContainer :: getData':无法将'this'指针从'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;

}

3 个答案:

答案 0 :(得分: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
}

超类不能对子类做出任何保证(合同)。

切片(,形式)
分配成员时唯一的保证是超类中的成员。这是一种切片形式;只复制(分配)超类成员。

可以创建一个虚拟分配方法,但同样,孩子不知道参数是表兄还是兄弟(参见上面的多态)。

<强>摘要 不要将赋值运算符放在超类或父类中。如果您的超类具有数据成员,请创建一个 protected 方法,以指定超类的成员。不要推断有关子类的任何内容。

答案 1 :(得分: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引用。这与作业无关。

有很多方法可以完成这项工作:

  • 不要在const引用上调用无用的getData()
  • getData()
  • 提供常量重载
  • 提供专用的const通知回调
  • 完全沟渠分配(无论如何,在多态类层次结构中这是一个非常糟糕的主意)

答案 2 :(得分:0)

好的,我得到了编译 - 我需要了解更多关于&#34; const&#34;的语义。我知道这是一个人为的例子。

的#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;
};