为什么'virtual'是派生类中重写方法的可选项?

squ*_*art 15 c++ virtual derived-class

当一个方法virtual在类中声明时,它的派生类中的覆盖也会被自动考虑virtual,并且C++语言virtual在这种情况下使该关键字成为可选:

class Base {
    virtual void f();
};
class Derived : public Base {
    void f(); // 'virtual' is optional but implied.
};
Run Code Online (Sandbox Code Playgroud)

我的问题是:选择的理由是什么virtual

我知道编译器并不是绝对必要的,但我认为如果编译器强制执行这样的约束,开发人员将会受益.

例如,有时当我阅读其他人的代码时,我想知道一个方法是否是虚拟的,我必须追踪它的超类来确定它.而一些编码标准(谷歌)使得将virtual关键字放在所有子类中是"必须的" .

Kor*_*icz 11

是的,在这种情况下让编译器强制执行虚拟会更好,并且我同意这是为了向后兼容而维护的设计错误.

然而,没有它,有一个技巧是不可能的:

class NonVirtualBase {
  void func() {};
};

class VirtualBase {
  virtual void func() = 0;
};

template<typename VirtualChoice>
class CompileTimeVirtualityChoice : public VirtualChoice {
  void func() {}
};
Run Code Online (Sandbox Code Playgroud)

有了上面我们有编译时选择我们想要func的虚拟性:

CompileTimeVirtualityChoice<VirtualBase> -- func is virtual
CompileTimeVirtualityChoice<NonVirtualBase> -- func is not virtual
Run Code Online (Sandbox Code Playgroud)

...但同意,这对于寻求功能虚拟性的成本来说是一个小小的好处,而我自己,我总是尝试在适用的地方打字虚拟.


Den*_*ose 6

作为相关注释,在C++ 0x中,您可以选择通过新属性语法强制显示覆盖.

struct Base {
  virtual void Virtual();
  void NonVirtual();
};

struct Derived [[base_check]] : Base {
  //void Virtual(); //Error; didn't specify that you were overriding
  void Virtual [[override]](); //Not an error
  //void NonVirtual [[override]](); //Error; not virtual in Base
  //virtual void SomeRandomFunction [[override]](); //Error, doesn't exist in Base
};
Run Code Online (Sandbox Code Playgroud)

您还可以指定何时通过[[hiding]]属性隐藏成员.它使你的代码更加冗长,但它可以在编译时捕获许多恼人的错误,就像你做了void Vritual()而不是void Virtual()在你打算覆盖现有函数时最终引入了一个全新的函数.