派生类何时需要将方法实现为const?

时间:2017-01-22 05:49:10

标签: c++ oop const

为什么CC::onError在下面的示例中不需要是const? BB:onError必须是const else编译器错误。

BB需要将onError实现为const else编译器错误。

CC可以实现为非const。为什么呢?

class AA  {
public:
    AA() {};
    virtual ~AA() {};

    // On any error
    virtual void onError(int32_t error) const = 0;
};

class BB : public AA {
public:
    BB() {};
    virtual ~BB() {};

    virtual void onError(int32_t error) const {
        //changing x is invalid here due to const
        //method required to be const else compiler error
    }
protected:
    int x;
};

class CC : public BB {
public:
    CC() {};
    virtual ~CC() {};

    virtual void onError(int32_t error)  {
        x = 5;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    CC c;
    return 0;
}

3 个答案:

答案 0 :(得分:2)

  

为什么在下面的例子中CC :: onError不需要是const?

因为成员函数不需要是const

问题是您希望它覆盖A::onError,这就是C ++ 11引入override关键字的原因。 这是一个微妙的错误,但事实是你并没有覆盖A::onError。您在C中声明了一个实际隐藏A::onError的新虚拟成员函数 试着用这个:

class CC : public BB {
public:
    CC() {};
    virtual ~CC() {};

    virtual void onError(int32_t error) override  {
        x = 5;
    }
};

编译器会明确告诉你错误是什么:

  

错误:'virtual void CC :: onError(int32_t)'标记为'覆盖',但不覆盖

另一方面,以下代码是正确的(至少它会按预期覆盖A:onError)但是由于它不能编译,因此无法修改x为{ {1}} onError

const

当然,除非您将virtual void onError(int32_t error) const override { x = 5; } 定义为x

mutable

我不推荐它,因为mutable int x; 适用于略有不同的情况,但it works

答案 1 :(得分:0)

AA::onError() const是纯虚拟的,即你必须在后代类(BB)中为它提供定义。注意,const是方法签名的一部分。

CC在祖先(BB)中定义onError() const,当您定义BB::onError()时,它不会覆盖BB::onError() const,因为其签名不同。您只需定义一个新方法。

答案 2 :(得分:0)

派生类中的非const方法不能覆盖基类中的const方法,即使所有参数类型都相同也是如此。函数C::onError隐藏函数B::onError而不是覆盖函数。

对于B::onError,与A::onError具有不同的cv资格是合法的,但由于A::onError是纯粹的,因此必须 some < / em>非纯粹的覆盖以便进入具体的类。如果B::onErrorC::onError 非const,则C是一个抽象类。问题最终是C,而不是B,因为C是您尝试实例化的内容。