【问题标题】:Missing 'virtual' qualifier in function declarations函数声明中缺少“虚拟”限定符
【发布时间】:2008-12-04 12:30:23
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c++ inheritance virtual


    【解决方案1】:

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

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

    参考:MSDN 上的Virtual Functions。向下滚动页面查看

    virtual 关键字可以在以下情况下使用 在 a 中声明覆盖函数 派生类,但没有必要; 虚函数的覆盖是 总是虚拟的。

    【讨论】:

    • 优秀。但是添加它并没有任何害处,对于第一次查看代码的人来说,它可能是有益的?
    • 添加它的唯一危害是,如果从基类中删除了 virtual ,大概也应该从所有派生类中删除它。但是进行重构的人无论如何都必须意识到对派生类的影响,所以我不会认为这是一个问题。
    【解决方案2】:

    这是一个不需要声明覆盖函数 virtual 的有趣结果:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2016-09-19
          • 2014-02-01
          • 1970-01-01
          • 2021-04-07
          • 1970-01-01
          • 1970-01-01
          • 2015-10-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多