编译器:GCC
在下面的代码中,所有 3 个 Foo() 的签名都是Foo(bool b),但是有人更新了代码并忘记了更改DeriveB::Foo。这通过了编译。我们怎样才能防止这种错误呢?
class Base {
virtual Foo(bool b, int i);
}
class DerivedA : public Base {
Foo(bool b, int i);
}
class DerivedB : public Base {
Foo(bool b);
}
编译器:GCC
在下面的代码中,所有 3 个 Foo() 的签名都是Foo(bool b),但是有人更新了代码并忘记了更改DeriveB::Foo。这通过了编译。我们怎样才能防止这种错误呢?
class Base {
virtual Foo(bool b, int i);
}
class DerivedA : public Base {
Foo(bool b, int i);
}
class DerivedB : public Base {
Foo(bool b);
}
说明override符可能是您想要的。如果你Foo在派生类的声明中使用它,你会得到一个错误,DerivedB::Foo因为它有一个不同的签名。
class Base {
virtual Foo(bool b, int i);
}
class DerivedA : public Base {
Foo(bool b, int i) override; // would be fine
}
class DerivedB : public Base {
Foo(bool b) override; // gives an error
}
如果派生类中的函数与基类中的函数具有不同的签名,或者基类中的函数未声明,则会出错virtual。
没有办法强迫人们在派生类中使用覆盖说明符,所以你仍然必须记住使用它。但它至少可以在更改函数签名时捕获错误。有关覆盖的更多信息,请查看此处。
在 C++11 中,您可以使用说明override符,我相信 MSVC 也支持它作为 C++03 代码的扩展。
如果您使用的是 g++ 或 clang,那么传递-Woverloaded-virtual给编译器就是我所想的。对于上面的示例,g++ 报告:
so_virt.cc:2:16: warning: ‘virtual void Base::Foo(bool, int)’ was hidden [-Woverloaded-virtual]
virtual void Foo(bool b, int i);
^
so_virt.cc:10:8: warning: by ‘void DerivedB::Foo(bool)’ [-Woverloaded-virtual]
void Foo(bool b);
class Base {
virtual Foo(bool b, int i) = 0;
}
class DerivedA : public Base {
Foo(bool b, int i);
}
class DerivedB : public Base {
Foo(bool b);
}
注意我是如何附加=0到virtual Foo(bool b, int i) = 0