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 :(得分: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)
以下是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
要启用这两个警告,您可以使用以下选项之一:
使用代码启用以上两个警告。
#pragma warning(default:4263)
#pragma warning(default:4266)
在项目设置中启用以上两个警告> C / C ++>命令行然后输入/ w34263 / w34266。这里/ wNxxxx选项意味着在级别N中启用xxxx警告(N = 3是默认级别)。你也可以使用/ wdNxxxx来禁用N级的xxxx警告。