Safely override C++ virtual functions
我有一个带有虚函数的基类,我想在派生类中重写该函数。有没有办法让编译器检查我在派生类中声明的函数是否实际重写了基类中的函数?我想添加一些宏或确保不会意外地声明新函数的东西,而不是重写旧函数。
举个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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); } |
这里,调用
有没有办法避免这个问题,我能告诉编译器或者其他工具帮我检查一下吗?有什么有用的编译器标志(最好是g++)?你如何避免这些问题?
由于G++ 4.7,它确实理解了新的C++ 11 EDCOX1×0关键字:
1 2 3 4 5 6 | 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 C的EDCOX1×0 }关键字不是C++的一部分。
在gcc中,
据我所知,你不能把它抽象化吗?
1 2 3 4 5 6 | class parent { public: virtual void handle_event(int something) const = 0 { // boring default code } }; |
我想我在www.parashift.com上看到过,实际上您可以实现一个抽象方法。这对我个人来说是有意义的,它所做的唯一一件事就是强制子类实现它,没有人说过它不被允许有一个实现本身。
在MSVC中,即使不是为clr编译,也可以使用clr
在G++中,在所有情况下都没有直接的强制执行方法;其他人在如何使用
在msvc++中,可以使用关键字
1 2 3 4 5 6 | class child : public parent { public: virtual void handle_event(int something) override { // new exciting code } }; |
使函数成为抽象的,这样派生类除了重写它之外别无选择。
@Ray您的代码无效。
1 2 3 4 5 6 | class parent { public: virtual void handle_event(int something) const = 0 { // boring default code } }; |
抽象函数不能以内联方式定义实体。必须修改为
1 2 3 4 5 6 | class parent { public: virtual void handle_event(int something) const = 0; }; void parent::handle_event( int something ) { /* do w/e you want here. */ } |
我建议你稍微改变一下逻辑。它可能工作,也可能不工作,这取决于你需要完成什么。
handle_Event()仍然可以执行"无聊的默认代码",但它不是虚拟的,在您希望它执行"新的令人兴奋的代码"时,让基类调用一个抽象方法(即必须重写),该方法将由您的子类提供。
编辑:如果您稍后决定您的一些后代类不需要提供"新的令人兴奋的代码",那么您可以将抽象更改为虚拟的,并提供该"插入的"功能的空基类实现。
如果基类函数变为隐藏,编译器可能会发出警告。如果是,启用它。这将捕获参数列表中的常量冲突和差异。不幸的是,这不会发现拼写错误。
例如,这是微软Visual C++中的C4263警告。