我有一个带有虚函数的基类,我想在派生类中重写该函数.有没有办法让编译器检查我在派生类中声明的函数是否实际覆盖了基类中的函数?我想添加一些宏或某些东西,以确保我不会意外地声明一个新的功能,而不是覆盖旧的功能.
举个例子:
class parent { public: virtual void handle_event(int something) const { // boring default code } }; class child : public parent { public: virtual void handle_event(int something) { // new exciting code } }; int main() { parent *p = new child(); p->handle_event(1); }
这里parent::handle_event()
调用而不是child::handle_event()
,因为child的方法错过了const
声明,因此声明了一个新方法.这也可能是函数名中的拼写错误或参数类型中的一些细微差别.如果基类的接口发生更改并且某些派生类未更新以反映更改,则也很容易发生.
有没有办法避免这个问题,我能以某种方式告诉编译器或其他工具为我检查这个吗?任何有用的编译器标志(最好是g ++)?你如何避免这些问题?
从g ++ 4.7开始,它确实理解了新的C++ 11 override
关键字:
class child : public parent { public: // force handle_event to override a existing function in parent // error out if the function with the correct signature does not exist void handle_event(int something) override; };
像C#的override
关键字不是C++的一部分.
在gcc中,-Woverloaded-virtual
警告不要使用相同名称的函数隐藏基类虚函数,但是它不会覆盖它.但是,它不会保护您免于因错误拼写函数名称本身而无法覆盖函数.
据我所知,你不能把它抽象化吗?
class parent { public: virtual void handle_event(int something) const = 0 { // boring default code } };
我以为我在www.parashift.com上看到你实际上可以实现一个抽象方法.这对我个人来说是有意义的,它唯一能做的就是强制子类来实现它,没有人说它不允许有自己的实现.
在MSVC中,override
即使您没有编译CLR ,也可以使用CLR 关键字.
在g ++中,没有直接的方法可以在所有情况下执行; 其他人已经就如何捕捉签名差异给出了很好的答案-Woverloaded-virtual
.在将来的版本中,有人可能会__attribute__ ((override))
使用C++ 0x语法添加类似或等效的语法.
在MSVC++中,您可以使用关键字override
class child : public parent { public: virtual void handle_event(int something) override { // new exciting code } };
override
适用于MSVC++中的本机代码和CLR代码.
使函数成为抽象,以便派生类除了覆盖它之外别无选择.
@Ray您的代码无效.
class parent { public: virtual void handle_event(int something) const = 0 { // boring default code } };
抽象函数不能具有内联定义的实体.它必须修改成为
class parent { public: virtual void handle_event(int something) const = 0; }; void parent::handle_event( int something ) { /* do w/e you want here. */ }