为什么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;
}
答案 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::onError
和C::onError
都非const,则C
是一个抽象类。问题最终是C
,而不是B
,因为C
是您尝试实例化的内容。