不应该有虚拟功能隐藏的警告吗?
Shouldn't there be a warning for virtual function hiding?
在Scott Meyers的《有效C++:改进程序和设计的55种具体方法》(第3版)第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()
太多缺乏经验的程序员对这条消息的回应是:对自己来说,"当然
D::f
隐藏了B::f
——这就是它应该做的!"错了。这个编译器试图告诉你在B中声明的未在D中重新声明;相反,它被隐藏了完全(关于为什么会这样做的说明,请参见第33项)。忽略这个编译器警告几乎肯定会导致错误的程序行为,然后进行大量调试以发现编译器首先检测到。
但是我的编译器不会给出任何警告,即使使用-Wall
也是如此。为什么我的编译器(GCC)不发出警告?
正如"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,它似乎不那么相关了。
- 警告处理为错误这里有什么问题
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- cppcheck在const std::string[]上引发警告
- GCC对可能有效的代码抛出init list生存期警告
- 如何在BST的这个简单递归实现中消除警告
- 这是我尝试让用户将值输入到数组中.然后将其隐藏为大量的星号
- 关于std::move的使用,是否有编译警告
- g++ 在某个类成员未初始化时不发出警告
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 如何在外部库中隐藏汇编中的警告
- libc++ 持续时间隐藏警告不正确
- 编译器不应该对派生类中隐藏的基本结构的成员变量发出警告吗?
- 如何在 ubuntu 12.10 中隐藏 g++ c++11 编译警告
- 不应该有虚拟功能隐藏的警告吗?
- 如何避免Visual Studio下的名称隐藏警告
- 对于隐藏具有类似原型的非虚拟方法没有警告(g++ 4.4)
- 使用 g++ 编译C++时,"隐藏构造函数"警告是什么意思?
- 如何隐藏链接器警告
- 使用makefile隐藏clang警告