如何在超类中使用const方法?

How do i use a const method in a superclass

本文关键字:const 方法 超类      更新时间:2023-10-16

好的,我再试一次。我不是一个有经验的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;
}

我强烈建议不要在父类(或父类)中放置赋值操作符。

这里有两个主要问题: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方法来分配超类的成员。不要对子类进行任何推断。

错误信息非常清楚。

 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调用它。这与赋值无关。

有很多方法可以实现:

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

好的,我得到了它编译-我需要了解更多关于"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;
};