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

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编译将会失败......)

链接地址: http://www.djcxy.com/p/89621.html

上一篇: Requiring virtual function overrides to use override keyword

下一篇: What is the purpose of the "final" keyword in C++11 for functions?