在浏览一些旧代码时,我遇到了类似于以下内容的内容:
class Base
{
public:
virtual int Func();
...
};
class Derived : public Base
{
public:
int Func(); // Missing 'virtual' qualifier
...
};
代码编译良好(MS VS2008)没有警告(级别4)并且它按预期工作 - Func
是虚拟的,即使派生类中缺少虚拟限定符。现在,除了引起一些混淆之外,这段代码是否存在任何危险,或者我应该更改所有内容,添加virtual
限定符?
答案 0 :(得分:10)
virtual
将被传递给派生类中的所有重写函数。添加关键字的唯一真正好处是表示您的意图,Derived类定义的随意观察者将立即知道Func
是虚拟的。
即使扩展Derived的类也会有虚拟Func方法。
MSDN上的参考:Virtual Functions。向下滚动页面以查看
虚拟关键字可用于 在a中声明覆盖函数 派生类,但没有必要; 虚函数的覆盖是 总是虚拟的。
答案 1 :(得分:2)
这是一个有趣的结果,不需要声明覆盖函数虚拟:
template <typename Base>
struct Derived : Base
{
void f();
};
Derived的f是否为虚拟取决于Derived是否使用具有正确签名的虚函数f的Base进行实例化。
答案 2 :(得分:0)
有人告诉我,一些不符合规范的旧C ++编译器需要为所有子类设置虚拟。这不再是问题了。
答案 3 :(得分:0)
遵循这种做法的一个危险是人们可能没有意识到他们需要虚拟关键字用于虚拟的功能。这很可能是来自没有非虚函数概念的语言的人(例如:Java,REALbasic)。作为推论,你无法分辨虚拟被故意省略的时间,因为一个函数应该是非虚拟的。
我怀疑一些代码分析工具也可能不够智能,无法获取继承的虚拟化。