C++ 如果一个虚方法在子类中声明为virtual,会有什么区别吗?

C++ 如果一个虚方法在子类中声明为virtual,会有什么区别吗?,c++,overriding,virtual,C++,Overriding,Virtual,我经常看到代码(例如),其中重写也被声明为虚拟的,即使类不打算再次被子类化。例如 class A { virtual void foo(); } class B : public A { virtual void foo(); } // there is no subclass of B (and most likely there will never be one) 在我的天真C++初学者的思想中,我发现不声明::Foo虚拟,以避免它被重写,这是更清楚、更明确的。即 cla

我经常看到代码(例如),其中重写也被声明为虚拟的,即使类不打算再次被子类化。例如

class A {
    virtual void foo();
}
class B : public A {
    virtual void foo();
}
// there is no subclass of B (and most likely there will never be one)
在我的天真C++初学者的思想中,我发现不声明<代码>::Foo虚拟,以避免它被重写,这是更清楚、更明确的。即

class B : public A {
     void foo();
}
我编写的许多方法都不是要重写的。另一方面,我理解
virtual
表示该方法被设计为被重写。我想这只是口味的问题,但我不是100%确定:


如果
B::foo()
声明为
virtual
(假设
B
不会用作基类),它会有什么区别吗?
不会,它不会有任何区别。如果
A::foo
在基类中声明为
virtual
B::foo
也为virtual:无论您是否声明为virtual。

否,都没有任何区别。如果
A::foo
在基类中声明为
virtual
B::foo
也为virtual:无论您是否声明为virtual。

不需要在派生类中标记重写的虚拟方法
virtual
。在派生最少的类中决定方法是否为虚方法

但是,在派生类中显式标记虚方法
virtual
是一个好主意,原因有两个:

  • 它可以作为代码未来读者的文档。那可能是你,所以这应该是一个强有力的激励
  • 如果有人决定删除基类中的
    virtual
    限定符,编译器可以在应用程序发布之前捕获错误,并发出警告。不过,在这种情况下,不需要特定实现发出诊断


  • 如果编译器支持C++11,建议在派生类中使用,因为它会执行额外的验证。如果基类方法未声明为
    virtual
    ,但派生类使用了
    重写
    说明符,则实现需要发出错误。

    不要求在派生类中标记重写的虚拟方法
    virtual
    。在派生最少的类中决定方法是否为虚方法

    但是,在派生类中显式标记虚方法
    virtual
    是一个好主意,原因有两个:

  • 它可以作为代码未来读者的文档。那可能是你,所以这应该是一个强有力的激励
  • 如果有人决定删除基类中的
    virtual
    限定符,编译器可以在应用程序发布之前捕获错误,并发出警告。不过,在这种情况下,不需要特定实现发出诊断


  • 如果编译器支持C++11,建议在派生类中使用,因为它会执行额外的验证。如果基类方法未声明为
    virtual
    ,但派生类使用了
    重写
    说明符,则实现需要发出错误。

    方法不会丢失is
    virtual
    限定符,因此如果
    a::foo()
    是virtual,
    B::foo()
    也是
    虚拟的
    ,即使没有重复
    B::foo()
    声明中的关键字

    override
    之前,在派生类中重复
    virtual
    可能是一种风格,要记住它是一种被重写的方法,现在我们可以使用
    override
    来代替(编译器检查它是否正确,而不能简单地使用
    virtual

    我编写的许多方法都不是要重写的


    因此,您可以将它们标记为
    final
    以禁止重写该方法(如果有意义,您也可以将类标记为final)。

    方法不会丢失的是
    virtual
    限定符,因此,如果
    A::foo()
    是virtual,那么
    B::foo()
    即使没有重复
    B::foo()中的关键字,也是
    virtual
    声明

    override
    之前,在派生类中重复
    virtual
    可能是一种风格,要记住它是一种被重写的方法,现在我们可以使用
    override
    来代替(编译器检查它是否正确,而不能简单地使用
    virtual

    我编写的许多方法都不是要重写的


    因此,您可以将它们标记为
    final
    以禁止重写该方法(如果有意义,您也可以将类标记为final)。

    No,
    foo
    将自动在
    B
    虚拟
    ,因为它在
    A
    中。不过,把它留在那里也没什么坏处。特别是如果有人想从
    B
    中派生,那么他们就知道
    foo
    虚拟的
    ,而不需要遍历继承。将
    覆盖
    放进去实际上至少会迫使编译器检查它。正如@CoryKramer所说,这是不需要的,但它也不会伤害他人,并且有利于其他人的可读性和文档编制。@CoryKramer,所以无论我是否明确地将
    virtual
    放在
    B
    中,它都不会对子类产生影响?如果这是真的,也许我应该改变我的习惯,总是把
    virtual
    也放在子类中…@juanchopanza它确实是一个副本。然而,我认为我很好地提出了“好的风格”,并得到了好的答案,而没有使问题过于宽泛或基于观点。我认为这方面没有包含在副本中。不,
    foo
    将在
    B
    中自动成为
    virtual
    ,因为它在
    A
    中。不过,把它留在那里也没什么坏处。特别是如果有人想从
    B
    中派生,那么他们就知道
    foo
    virtual
    ,而不必走到inheri