要求虚拟函数覆盖使用覆盖关键字
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
。
看起来GCC 5.1版本增加了我正在寻找的警告:
-Wsuggest-override
警告重写未使用override关键字标记的虚拟函数。
使用-Wsuggest-override
-Werror=suggest-override
编译将强制所有覆盖使用override
。
有两件事你可以做。
首先,Clang 3.5及更高版本具有-Winconsistent-missing-override
警告(由-Wall
触发)。 这不适用于你的例子,但只有当你将class B
加入void foo() override {}
而不是class C
。 你真正想要的是-Wmissing-override
,找到所有丢失的override
,而不仅仅是不一致的丢失override
。 目前没有提供,但您可能会抱怨Clang邮件列表,他们可能会添加它。
其次,你使用Howard Hinnant的技巧临时添加final
到基类成员函数并重新编译。 然后,编译器将定位所有尝试覆盖virtual
基本成员函数的派生类。 然后你可以修复丢失的部分。 这是一个更多的工作,并且需要在类层次扩展时经常重新检查。
我用-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编译将会失败......)
上一篇: Requiring virtual function overrides to use override keyword
下一篇: What is the purpose of the "final" keyword in C++11 for functions?