C 11添加了<code>override</code>,以确保您编写的打算重写基类虚拟函数的成员函数实际执行(或不会编译)。
但在大型对象层次结构中,有时您可能会意外地编写一个成员函数,该函数在您不打算的情况下重写基类virtual!例如:
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
}
};
有没有某种编译器标志/扩展至少会在< code>C::foo上发出警告?为了可读性和正确性,我只想强制所有的覆盖都使用< code>override。
我看到的-Weror=建议重写
的问题是它不允许您编写以下内容:
void f() final {...}
即使这里有一个隐式的< code>override。< code >-Werror = suggest-override 不会忽略这一点(这是应该的,因为< code>override在这种情况下是多余的)
但要比那更复杂…如果你写
virtual void f() final {...}
这意味着完全不同于
virtual void f() override final {...}
第一种情况不需要覆盖任何东西!第二个有。
因此,我假设GCC检查是以这种方式实现的(即有时接受冗余的<code>override</code>),以便正确处理最后一种情况。但这并不能很好地发挥作用,例如,当final足够时,clang-time将正确删除覆盖(但GCC编译将失败…)
你可以做两件事。
首先,Clang 3.5及更高版本有一个-Winconaced-noised-overide
警告(由-Wall
触发)。这对您的示例不太起作用,但前提是您要将空foo()覆盖{}
添加到类B
而不是在类C
中。您实际上想要的是-Wisacing-overide
,以定位所有丢失的覆盖
,而不仅仅是不一致的丢失。目前没有提供,但您可能会在Clang邮件列表中投诉,他们可能会添加它。
其次,您使用Howard Hinnant的技巧将最终
临时添加到基类成员函数并重新编译。然后,编译器将找到所有试图覆盖虚拟
基本成员函数的进一步派生类。然后,您可以修复丢失的那些。这需要更多的工作,并且需要在类层次结构扩展时经常重新检查。
看起来GCC 5.1版本添加了我一直在寻找的警告:
-W建议-覆盖
使用 -Wsuggest-override -Werror=suggest-override
进行编译将强制所有覆盖都使用覆盖
。
未解决原始关闭原因 关键字虚拟允许派生类在需要多态的情况下覆盖,这可以在有或没有关键字覆盖的情况下关闭。添加覆盖如何影响程序? 示例代码:
C++中的面向对象的变成都是围绕类,继承和虚函数进行的。其中最基础的一部分就是,派生类中的虚函数会覆盖掉基类中对应的虚函数。但是令人心痛的意识到虚函数重载是如此容易搞错。这部分的语言特性甚至看上去是按照墨菲准则设计的,它不需要被遵从,但是要被膜拜。 因为覆盖“overriding”听上去像重载“overloading”,但是它们完全没有关系,我们要有一个清晰地认识,虚函数(覆盖的函数)可以通过基类
关于在C中使用关键字final,我有一个问题。我知道虚函数是在基类中声明的成员函数,它应该在派生类中重写。通过动态绑定,将根据负责调用的对象的类型调用适当的方法。但是,为了防止基类中的成员函数在任何派生类中被重写,我们将使用final关键字。 为什么我们使用“最终”来防止基类中的成员函数在派生类中被覆盖,同时我们仍然必须一起使用关键字VIRTUAL(允许覆盖)。 我试图删除虚拟这个词,但我得到一个
条款12:使用override声明重载函数 在C++面向对象的世界里,涉及的概念有类,继承,虚函数。这个世界最基本的概念是派生类的虚函数重写基类同名函数。令人遗憾的是虚函数重写可能一不小心就错了。给人感觉语言的这一部分设计观点是墨菲定律不是用来遵守的,只是值得尊敬的。 鉴于"重写"听起来像"重载",尽管两者完全不相关,下面就通过一个派生类和基类来说明什么是虚函数重写: class Base {
我一直在使用越来越多的C11,我遇到了一些我在任何地方都找不到的东西。当我们从基指针中删除派生类时,我们需要有虚拟析构函数;但有时父析构函数需要“纯”,这在C中是不可能的。所以,我的问题是,默认值是否可以用于虚拟析构函数?我已经试过了,而且效果不错,但我不知道它是否安全,因为互联网上没有任何关于它的信息。 编辑:为了澄清这个问题,我说的是使用
在以下示例中: < code>clang-tidy对等级< code>B给出以下警告: “virtual”是多余的,因为此函数已声明为“override” 从class中删除关键字似乎允许调用链中的所有析构函数,但我希望确保没有遗漏任何内容。