我最近遇到了一个令人沮丧的问题,归结为一个非常简单的编码错误。请考虑以下代码:
#include <iostream>
class Base
{
public:
void func() { std::cout << "BASE" << std::endl; }
};
class Derived : public Base
{
public:
virtual void func() { std::cout << "DERIVED" << std::endl; }
};
int main(int argc, char* argv[])
{
Base* obj = new Derived;
obj->func();
delete obj;
return 0;
}
输出
BASE
显然(对于这种情况),我的意思是将虚拟关键字放在Base :: func上,以便在main中调用Derived :: func。我意识到这可能(可能)是由c ++标准允许的,并且可能有充分的理由,但在我看来,99%的时间这将是一个编码错误。但是,当我使用g ++和我能想到的所有-Wblah选项编译时,没有产生任何警告。
当基类和派生类都具有相同名称的成员函数时,有没有办法生成警告,其中派生类的函数是虚函数而基类的函数不是?
答案 0 :(得分:5)
在Visual C ++中,您可以使用override
扩展名。像这样:
virtual void func() override { std::cout << "DERIVED" << std::endl; }
如果函数实际上没有覆盖基类方法,则会出错。我将它用于所有虚拟功能。通常我会像这样定义一个宏:
#ifdef _MSC_VER
#define OVERRIDE override
#else
#define OVERRIDE
#endif
所以我可以这样使用它:
virtual void func() OVERRIDE { std::cout << "DERIVED" << std::endl; }
我在g ++中找到了类似的东西,却找不到类似的概念。
我在Visual C ++中唯一不喜欢的是你不能让编译器对所有被覆盖的函数都要求它(或至少警告它)。
答案 1 :(得分:3)
我不知道任何g ++标志会对此产生警告(并不是说没有),但我会说这是一个非常罕见的错误。大多数人首先编写基类,作为使用纯虚函数的接口。如果你说过:
void func() = 0;
然后你会得到语法错误。
答案 2 :(得分:1)
man gcc
-Woverloaded-virtual(仅限C ++和Objective-C ++) 当函数声明隐藏基类中的虚函数时发出警告。例如,在:
struct A {
virtual void f();
};
struct B: public A {
void f(int);
};
the "A" class version of "f" is hidden in "B", and code like:
B* b;
b->f();
will fail to compile.