是的,您应该更喜欢在覆盖基类行为时使用override
而不是。virtual
因为它可能导致可能的错误
这怎么可能导致错误?这是一个例子,
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo() {
std::cout << "BASE foo" << std::endl;
}
void bar() {
std::cout << "BASE bar" << std::endl;
}
};
class A : public Base{
public:
void foo() override {
std::cout << "A foo" << std::endl;
}
virtual void bar() {
std::cout << "A bar" << std::endl;
}
};
class B : public A {
public:
void bar() override {
std::cout << "B bar" << std::endl;
}
};
int main(int argc, char *argv[])
{
B b;
A *a = &b;
Base *base = &b;
base->foo();
a->foo();
base->bar();
a->bar();
return 0;
}
输出将是
A foo
A foo
BASE bar
B bar
foo()
被正确覆盖但bar
不是,在某些情况下会被隐藏。bar()
即使底层对象相同,调用也不会调用相同的方法
如果我们强制自己override
在覆盖时总是使用并且virtual
只定义新的虚函数,那么当我们尝试void bar() override {}
编译器时会抱怨error: ‘void A::bar()’ marked ‘override’, but does not override
这正是Autosar 规范定义以下规则的原因
规则 A10-3-1(必需、实现、自动) 虚函数声明应包含以下三个说明符之一:(1) virtual,(2) override,(3) final。
基本原理:指定这三个说明符中的一个以上以及虚函数声明是多余的,并且是潜在的错误来源。