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
,但派生类使用了重写说明符,则实现需要发出错误。方法不会丢失isvirtual
限定符,因此如果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