在C ++中对函数使用virtual
和override
是否危险?这是否会让你因重载而产生歧义?
显然必须在基类中使用virtual
,并且在派生类中不使用override
会很愚蠢,但使用virtual
实际上是有问题的 override
在派生类中?
尝试确定这是否是样式或正确性的问题。
示例:
class Widget {
virtual void transmogrify() = 0;
}
class Gadget : public Widget {
virtual void transmogrify() override {}
}
答案 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:虚拟函数应准确指定
virtual
,override
或final
中的一个原因
可读性。检测错误。编写显式
virtual
,override
或final
是自记录文档,使编译器能够捕获基类和派生类之间类型和/或名称的不匹配。但是,写这三者中的一个以上既是多余的,也是潜在的错误源。简单明了:
virtual
的意思恰好只有“这是一个新的虚拟函数”。override
的唯一含义是“这是一个非最终替代者”。final
的意思恰好是“这是最终的替代者”。
答案 2 :(得分:1)
在您的示例中,您说的是Gadget
方法transmogrify
virtual
- 如果某个类派生自Gadget
,那么transmogrify
函数将被派生类视为虚拟
override
- Gadget
类明确覆盖基类Widget
的{{1}}版本。
这两个关键作品是正交的,互不影响。关于transmogrify
关键字的好处是它向编译器声明您试图覆盖继承的虚函数。如果你在匹配基类上函数的函数签名时出错,它将无法编译,因为必须覆盖继承的函数,如果声明为override