2015-03-19 84 views
28

C++ 11添加了override以确保您编写的要覆盖基类虚函数的成员函数实际上(或不会编译)。要求虚函数覆盖以使用覆盖关键字

但是在一个大的对象层次结构中,有时候你可能会意外地写出一个成员函数,当你不打算这个函数时,它就会覆盖基类虚拟。例如:

struct A { 
    virtual void foo() { } // because obviously every class has foo(). 
}; 

struct B : A { ... }; 

class C : B { 
private: 
    void foo() { 
     // was intended to be a private function local to C 
     // not intended to override A::foo(), but now does 
    } 
}; 

有一些编译器标志/扩展至少会发布关于C::foo警告?为了可读性和正确性,我只是想强制所有覆盖使用override

+0

在现实中,你的功能将被命名为'GazimpleWidget(窗口小部件&W)'显然'C :: GazimpleWidget(Widget&w)'仍然会记住小部件。当你试图将'C :: GazimpleWidget()'缩写为'C :: GW()'时,你只会遇到这样的问题。不要这样做。 – MSalters 2015-03-19 13:23:12

+0

相关:http://stackoverflow.com/questions/13223277/how-to-enforce-the-override-keyword – 2015-03-19 13:23:25

+0

@MSalters我不明白的注释。 – Barry 2015-03-19 13:28:59

回答

21

貌似GCC 5.1版本增加完全warning我一直在寻找:

-Wsuggest-override
             警告有关覆盖未标明override关键字虚函数。

-Wsuggest-override-Werror=suggest-override编译然后将强制所有覆盖中使用override

10

你可以做两件事。

首先,Clang 3.5及更高版本有-Winconsistent-missing-override警告(由-Wall触发)。这不适用于您的示例,但前提是您要添加void foo() override {}class B而不是class C。你实际上想要的是-Wmissing-override,找到所有丢失的override,而不仅仅是不一致的丢失。目前没有提供,但您可能会抱怨Clang邮件列表,他们可能会添加它。

二,您暂时使用Howard Hinnant's trickfinal添加到基类成员函数并重新编译。然后,编译器将找到所有试图覆盖基本成员函数的派生类。然后你可以修复丢失的部分。这是一个更多的工作,并且需要在类层次扩展时经常重新检查。

0

海湾合作委员会和铿锵其他答案覆盖。下面是同为VC++从my other answer

下面是VC相关的警告编号++:

C4263 (level 4) 'function': member function does not override any base class virtual member function 
C4266 (level 4) 'function': no override available for virtual member function from base 'type'; function is hidden 

为了使这两个警告,您可以使用下列选项之一:

  1. 设置警告级别在项目设置中为4,然后禁用不需要的警告。这是我最喜欢的方式。要禁用不需要的级别4警告,请转到项目设置> C/C++>高级,然后在禁用特定警告框中输入警告号码。
  2. 使用代码启用上述两个警告。

    #pragma warning(default:4263) 
    #pragma warning(default:4266) 
    
  3. 启用上述项目设置> C/C++>命令行两次警告,然后输入/ w34263/w34266。这里/ wNxxxx选项表示在级别N中启用xxxx警告(N = 3是默认级别)。你也可以做/ wdNxxxx其禁用水平N的XXXX警告

0

-Werror=suggest-override看到的问题是,它不允许你写了以下内容:

void f() final {...} 

即使有这里是一个隐含的override。该-Werror=suggest-override不会忽略不这样(像它应该,因为override是多余的在这种情况下)

但它是比这更复杂......如果你写

virtual void f() final {...} 

这意味着完全不同的东西比

virtual void f() override final {...} 

第一种情况不需要重写任何东西!第二个呢。

所以我假设GCC检查,以这种方式实现(即有时接受冗余override),以获得最后的情况下,正确的。但是这不能很好地发挥,例如铿锵-整洁,这将正确地删除重写的时候最终是足够了(但当时GCC编译失败...)