虚拟功能隐藏不应该有警告吗?

时间:2014-10-14 02:34:57

标签: c++ gcc

在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)没有发出警告?

1 个答案:

答案 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它似乎不太相关。