我应该使用虚拟,覆盖,或两个关键字?

在过去的几个星期里,有些关于 virtualoverride的问题一直困扰着我的大脑。 我了解到,当使用虚函数进行继承时,必须添加 virtual,以便让编译器知道如何搜索正确的函数。 后来我还了解到,在 c + + 11中有一个新的关键字 -override。现在我有点困惑了: < strong > 我需要在程序中同时使用虚拟关键字和重写关键字吗? 还是只使用其中一个关键字更好?

为了解释我自己-我的意思的代码示例:

class Base
{
public:
virtual void print() const = 0;
virtual void printthat() const = 0;
virtual void printit() const = 0;
};


class inhert : public Base
{
public:
// only virtual keyword for overriding.
virtual void print() const {}


// only override keyword for overriding.
void printthat() const override {}


// using both virtual and override keywords for overriding.
virtual void printit() const override {}
};

最好的方法是什么?

135281 次浏览

重写函数时,从技术上讲,不需要编写 virtualoverride

原始的基类声明需要关键字 virtual将其标记为 Virtual。

在派生类中,通过与基类函数具有相同的类型,该函数是虚函数。

但是,当预期的重写在技术上不是重写时,override可以通过产生编译错误来帮助避免 bug。例如,函数类型与基类函数不完全一样。或者基类的维护改变了函数的类型,例如添加了一个默认的参数。

同样,派生类中的 virtual关键字可以确保函数在进一步的派生类中仍然是虚函数,从而使这种错误更加微妙。

所以一般的建议是,

  • 对基类函数声明使用 virtual
    这在技术上是必要的

  • 对派生类的重写使用 override(仅)。
    这有助于维护

例如:

struct Base { virtual void foo() {} };
struct Derived: Base { void foo() override {} };

备注:
1C + + 支持协变原始指针和原始引用结果。有了协方差,重写的类型就不完全一样了。它只是有一个兼容的类型。

根据 C + + 核心准则 C.128,每个虚函数声明应该指定 virtualoverridefinal正好一个

  • virtual: 对于基类中函数的“第一次”外观
  • override: 用于在从提供相同 (或协变)签名的 virtual函数的某个基类派生的类中重写该 virtual函数
  • 将覆盖标记为 不可战胜。也就是说,具有 final虚函数重写的类的派生物不能重写该虚函数。
struct A {
virtual void go() { puts("A"); }
};
struct B : A {
// Overrides A::go(). No need to specify `virtual` explicitly,
// it already implicitly is virtual and overrideable
void go() override { puts("B"); }
};
struct C : B {
void go() final { puts("C"); }
//virtual void go() override final { puts("C"); } would still compile,
// but it is considered, for lack of a better description, "extra"
};
struct D : C {
// Would produce error C3248 : 'C::go' : function declared as 'final' cannot be overridden by 'D::go'
//void go() override { puts("D"); }
};