在C ++ 11中同时使用virtual和override关键字有什么微妙之处吗?

时间:2015-04-20 23:42:39

标签: c++ c++11

在C ++中对函数使用virtualoverride是否危险?这是否会让你因重载而产生歧义?

显然必须在基类中使用virtual,并且在派生类中不使用override会很愚蠢,但使用virtual 实际上是有问题的 override在派生类中?

尝试确定这是否是样式或正确性的问题。

示例:

class Widget {
  virtual void transmogrify() = 0;
}

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

3 个答案:

答案 0 :(得分:32)

当您覆盖时,virtual关键字无效。派生函数是基类中定义的虚函数的签名匹配,将覆盖基本定义,并且将在vtable中输入覆盖,无论是否在派生类中使用virtual关键字。

如果未发生覆盖,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                 |

答案 1 :(得分:2)

是游戏的后期,但是this C++ Core Guideline在这里似乎很重要:

  

C.128:虚拟函数应准确指定virtualoverridefinal中的一个

     

原因

     

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

     

简单明了:

     
      
  • virtual的意思恰好只有“这是一个新的虚拟函数”。
  •   
  • override的唯一含义是“这是一个非最终替代者”。
  •   
  • final的意思恰好是“这是最终的替代者”。
  •   

答案 2 :(得分:1)

在您的示例中,您说的是Gadget方法transmogrify

的两个不同但重要的事情

virtual - 如果某个类派生自Gadget,那么transmogrify函数将被派生类视为虚拟

override - Gadget类明确覆盖基类Widget的{​​{1}}版本。

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