在Scott Meyers的Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)第9章中,它有一个名为项目53:注意编译器警告的部分。 Meyers说以下程序应该发出警告:
class B {
public:
virtual void f() const;
};
class D: public B {
public:
virtual void f();
};
并说:
我们的想法是
D::f
重新定义虚函数B::f
,但是 有一个错误:在B中,f是一个const成员函数,但在D中它是 没有声明const。我知道的一个编译器就是这样说的:warning: D::f() hides virtual B::f()
太多没有经验的程序员回答这个消息说 他们自己,#34;当然
D::f
隐藏B::f
- 这就是它应该做的事情!"错误。这个编译器试图告诉你f 在B中宣布未在D中重新宣布;相反,它被隐藏了 完全(参见第33项,了解为何如此)。忽略 这个编译器警告几乎肯定会导致错误的程序 行为,然后进行大量调试以发现这个问题 首先检测到编译器。
但是我的编译器没有发出任何警告,即使使用-Wall
也是如此。为什么我的编译器(GCC)没有发出警告?
答案 0 :(得分:3)
As" chris"指出,如果您使用-Woverloaded-virtual
,GCC会发出警告,但-Wall -Wextra
未启用此功能。在任何情况下,您都不需要编译器来查找它,您可以使用C ++ 11:
class B {
public:
virtual void f() const;
};
class D: public B {
public:
void f() override;
};
通过在打算覆盖虚拟方法时指定override
,如果签名错误,编译器将给出错误(而不仅仅是警告)。
关于-Woverloaded-virtual
,请注意它警告的不仅仅是const
:如果您定义具有相同名称和完全不同参数的新方法,它也会发出警告。这种事情发生在真正的代码库中,可能是非常有意的,所以这可能是为什么不能在任何粗粒度警告选项中启用它。我猜一个const
- 唯一的警告可能不错,但现在我们有C ++ 11它似乎不太相关。