4

在浏览一些旧代码时,我遇到了类似于以下内容的内容:

class Base
{
public:
    virtual int Func();
    ...
};

class Derived : public Base
{
public:
    int Func(); // Missing 'virtual' qualifier
    ...
};

代码编译良好(MS VS2008),没有警告(级别 4),它按预期工作 -Func即使派生类中缺少虚拟限定符,它也是虚拟的。现在,除了引起一些混乱之外,这段代码是否有任何危险,或者我应该全部更改,添加virtual限定符?

4

4 回答 4

10

virtual将被传递到派生类中的所有重写函数。添加关键字的唯一真正好处是表明您的意图,派生类定义的偶然观察者会立即知道这Func是虚拟的。

即使是扩展 Derived 的类也将具有虚拟 Func 方法。

参考: MSDN 上的虚拟功能。向下滚动页面查看

在派生类中声明重写函数时可以使用virtual关键字,但不是必需的;虚函数的覆盖总是虚函数。

于 2008-12-04T12:33:51.137 回答
2

这是不需要将覆盖函数声明为虚拟的有趣结果:

template <typename Base>
struct Derived : Base
{
    void f();
};

Derived 的 f 是否为虚函数取决于 Derived 是否使用具有正确签名的虚函数 f 的 Base 实例化。

于 2008-12-04T12:49:29.250 回答
0

曾经有人告诉我,非常旧的 C++ 编译器不符合规范,需要为所有子类设置 virtual。这不再是问题了。

于 2008-12-04T12:37:00.040 回答
0

遵循这种做法的一个危险是,人们可能没有意识到他们需要虚拟函数的 virtual 关键字。这很可能是来自没有非虚拟函数概念的语言(例如:Java、REALbasic)的人。作为推论,您无法判断何时故意省略了 virtual ,因为函数应该是非虚拟的。

我怀疑一些代码分析工具也可能不够聪明,无法识别继承的虚拟性。

于 2009-01-18T02:09:50.330 回答