要求虚函数覆盖使用override关键字

时间:2015-03-19 13:10:25

标签: c++ c++11 gcc override virtual

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

4 个答案:

答案 0 :(得分:31)

看起来GCC 5.1版本恰好添加了我正在寻找的warning

  

-Wsuggest-override
  关于覆盖未使用override关键字标记的虚函数的警告。

使用-Wsuggest-override -Werror=suggest-override进行编译会强制所有覆盖都使用override

答案 1 :(得分:13)

你可以做两件事。

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

其次,您使用Howard Hinnant's trick暂时添加virtual添加到基类成员函数并重新编译。然后,编译器将找到尝试覆盖{{1}}基本成员函数的所有其他派生类。然后你可以修复丢失的那些。当你的类层次结构扩展时,这需要更多的工作并且需要经常重新检查。

答案 2 :(得分:4)

我在-Werror=suggest-override看到的问题是它不允许您编写以下内容:

void f() final {...}

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

但它比那更复杂......如果你写

virtual void f() final {...}

这意味着与

完全不同的东西
virtual void f() override final {...}

第一种情况不需要覆盖任何东西!第二个。

所以我假设GCC检查以这种方式实现(即有时接受冗余override)以便最后一个案例正确。但这并不好,例如使用clang-tidy,当final结束时将正确删除覆盖(但GCC编译将失败......)

答案 3 :(得分:-1)

其他答案涵盖GCC和Clang。来自my other answer的VC ++也是如此:

以下是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警告。

相关问题