在 C++11 中同时使用虚拟关键字和覆盖关键字是否有任何细微之处

Are there any subtleties in using both the virtual and override keywords in C++11?

本文关键字:关键字 是否 覆盖 任何细 虚拟 C++11      更新时间:2023-10-16

C++函数上同时使用virtualoverride有危险吗?这是否会让您因超载而产生歧义?

显然,virtual必须在基类中使用,在派生类中不使用override是愚蠢的,但是在派生类中将virtualoverride一起使用实际上是有问题的吗?

试图确定这是风格问题还是正确性问题。

例:

class Widget {
  virtual void transmogrify() = 0;
}
class Gadget : public Widget {
  virtual void transmogrify() override {}
}

virtual 关键字在重写时不起作用。 作为基类中定义的虚拟函数的签名匹配的派生函数将覆盖基定义,并且无论派生类中是否使用 virtual 关键字,都将在 vtable 中输入覆盖。

因为如果不进行重写,override 关键字将导致编译错误,所以 virtual 关键字组合起来毫无用处。

在这里,有一个备忘单:

| Keyword used | Matching virtual function in base class | Result                   |
|--------------|-----------------------------------------|--------------------------|
| Neither      | No                                      | New non-virtual function |
| Neither      | Yes                                     | Override                 |
| virtual      | No                                      | New virtual function     |
| virtual      | Yes                                     | Override                 |
| override     | No                                      | Compile error            |
| override     | Yes                                     | Override                 |
| Both         | No                                      | Compile error            |
| Both         | Yes                                     | Override                 |

游戏来晚了,但这个C++核心指南在这里似乎很相关:

C.128:虚函数应该指定virtualoverridefinal中的一个

原因

可读性。检测错误。编写显式virtualoverridefinal是自我记录的,使编译器能够捕获基类和派生类之间的类型和/或名称不匹配。但是,编写这三者中的多个是多余的,并且是潜在的错误来源。

简单明了:

  • virtual的意思是"这是一个新的虚拟功能"。
  • override的意思是"这是一个非最终覆盖者"。
  • final的意思是确切的,而且只有"这是最终的覆盖者"。
在你的

例子中,你说的是关于Gadget方法的两件不同但重要的事情transmogrify

virtual - 如果一个类派生自Gadgettransmogrify函数将被派生类视为虚拟

override - Gadget类显式覆盖基类Widgettransmogrify版本。

这两部关键作品是正交的,互不影响。override 关键字的好处是,它向编译器声明您正在尝试覆盖继承的虚拟函数。如果您在基类上匹配函数的函数签名时出错,它将不会编译,因为如果声明为override,它必须覆盖继承的函数