缺少虚拟关键字的警告

时间:2009-12-16 17:47:39

标签: c++ g++

我最近遇到了一个令人沮丧的问题,归结为一个非常简单的编码错误。请考虑以下代码:

#include <iostream>

class Base
{
public:
    void func() { std::cout << "BASE" << std::endl; }
};

class Derived : public Base
{
public:
    virtual void func() { std::cout << "DERIVED" << std::endl; }
};

int main(int argc, char* argv[])
{
    Base* obj = new Derived;
    obj->func();
    delete obj;

    return 0;
}

输出

  

BASE

显然(对于这种情况),我的意思是将虚拟关键字放在Base :: func上,以便在main中调用Derived :: func。我意识到这可能(可能)是由c ++标准允许的,并且可能有充分的理由,但在我看来,99%的时间这将是一个编码错误。但是,当我使用g ++和我能想到的所有-Wblah选项编译时,没有产生任何警告。

当基类和派生类都具有相同名称的成员函数时,有没有办法生成警告,其中派生类的函数是虚函数而基类的函数不是?

3 个答案:

答案 0 :(得分:5)

在Visual C ++中,您可以使用override扩展名。像这样:

virtual void func() override { std::cout << "DERIVED" << std::endl; }

如果函数实际上没有覆盖基类方法,则会出错。我将它用于所有虚拟功能。通常我会像这样定义一个宏:

#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE
#endif

所以我可以这样使用它:

virtual void func() OVERRIDE { std::cout << "DERIVED" << std::endl; }

我在g ++中找到了类似的东西,却找不到类似的概念。

我在Visual C ++中唯一不喜欢的是你不能让编译器对所有被覆盖的函数都要求它(或至少警告它)。

答案 1 :(得分:3)

我不知道任何g ++标志会对此产生警告(并不是说没有),但我会说这是一个非常罕见的错误。大多数人首先编写基类,作为使用纯虚函数的接口。如果你说过:

void func() = 0;

然后你会得到语法错误。

答案 2 :(得分:1)

man gcc

-Woverloaded-virtual(仅限C ++和Objective-C ++)        当函数声明隐藏基类中的虚函数时发出警告。例如,在:

           struct A {
             virtual void f();
           };

           struct B: public A {
             void f(int);
           };

   the "A" class version of "f" is hidden in "B", and code like:

           B* b;
           b->f();

   will fail to compile.