安全地覆盖 C++ 虚函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/497630/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Safely override C++ virtual functions
提问by sth
I have a base class with a virtual function and I want to override that function in a derived class. Is there some way to make the compiler check if the function I declared in the derived class actually overrides a function in the base class? I would like to add some macro or something that ensures that I didn't accidentally declare a new function, instead of overriding the old one.
我有一个带有虚函数的基类,我想在派生类中覆盖该函数。有没有办法让编译器检查我在派生类中声明的函数是否实际上覆盖了基类中的函数?我想添加一些宏或确保我不会意外声明新函数的东西,而不是覆盖旧函数。
Take this example:
拿这个例子:
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);
}
Here parent::handle_event()
is called instead of child::handle_event()
, because the child's method misses the const
declaration and therefore declares a new method. This could also be a typo in the function name or some minor difference in the parameters types. It can also easily happen if the interface of the base class changes and somewhere some derived class wasn't updated to reflect the change.
这里parent::handle_event()
被调用而不是child::handle_event()
,因为孩子的方法错过了const
声明,因此声明了一个新方法。这也可能是函数名称的拼写错误或参数类型的一些细微差别。如果基类的接口发生更改并且某些派生类没有更新以反映更改,也很容易发生这种情况。
Is there some way to avoid this problem, can I somehow tell the compiler or some other tool to check this for me? Any helpful compiler flags (preferably for g++)? How do you avoid these problems?
有什么方法可以避免这个问题,我可以以某种方式告诉编译器或其他工具来帮我检查吗?任何有用的编译器标志(最好是 g++)?你如何避免这些问题?
采纳答案by Gunther Piez
Since g++ 4.7 it does understand the new C++11 override
keyword:
从 g++ 4.7 开始,它确实理解新的 C++11override
关键字:
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;
};
回答by CB Bailey
Something like C#'s override
keyword is not part of C++.
像 C# 的override
关键字这样的东西不是 C++ 的一部分。
In gcc, -Woverloaded-virtual
warns against hiding a base class virtual function with a function of the same name but a sufficiently different signature that it doesn't override it. It won't, though, protect you against failing to override a function due to mis-spelling the function name itself.
在 gcc 中,-Woverloaded-virtual
警告不要隐藏具有相同名称但签名完全不同的函数的基类虚函数,以至于它不会覆盖它。但是,它不会保护您不会因函数名称本身拼写错误而无法覆盖函数。
回答by Ray Hidayat
As far as I know, can't you just make it abstract?
据我所知,你不能把它抽象化吗?
class parent {
public:
virtual void handle_event(int something) const = 0 {
// boring default code
}
};
I thought I read on www.parashift.com that you can actually implement an abstract method. Which makes sense to me personally, the only thing it does is force subclasses to implement it, no one said anything about it not being allowed to have an implementation itself.
我以为我在 www.parashift.com 上读到您实际上可以实现一个抽象方法。这对我个人来说很有意义,它唯一做的就是强制子类实现它,没有人说它不允许自己有实现。
回答by Doug
In MSVC, you can use the CLR override
keyword even if you're not compiling for CLR.
在 MSVC 中,override
即使您没有为 CLR 进行编译,也可以使用 CLR关键字。
In g++, there's no direct way of enforcing that in all cases; other people have given good answers on how to catch signature differences using -Woverloaded-virtual
. In a future version, someone might add syntax like __attribute__ ((override))
or the equivalent using the C++0x syntax.
在 g++ 中,没有在所有情况下强制执行的直接方法;其他人已经就如何使用-Woverloaded-virtual
. 在未来的版本中,有人可能会__attribute__ ((override))
使用 C++0x 语法添加类似或等效的语法。
回答by bobobobo
In MSVC++ you can use keyword override
在 MSVC++ 中,您可以使用关键字override
class child : public parent {
public:
virtual void handle_event(int something) <b>override</b> {
// new exciting code
}
};
override
works both for native and CLR code in MSVC++.
override
适用于 MSVC++ 中的本机和 CLR 代码。
回答by Tanveer Badar
Make the function abstract, so that derived classes have no other choice than to override it.
使函数抽象,以便派生类别无选择,只能覆盖它。
@Ray Your code is invalid.
@Ray 您的代码无效。
class parent {
public:
virtual void handle_event(int something) const = 0 {
// boring default code
}
};
Abstract functions cannot have bodies defined inline. It must be modified to become
抽象函数不能具有内联定义的主体。必须修改为
class parent {
public:
virtual void handle_event(int something) const = 0;
};
void parent::handle_event( int something ) { /* do w/e you want here. */ }
回答by JMD
I would suggest a slight change in your logic. It may or may not work, depending on what you need to accomplish.
我建议你的逻辑稍微改变一下。它可能会也可能不会起作用,这取决于您需要完成什么。
handle_event() can still do the "boring default code" but instead of being virtual, at the point where you want it to do the "new exciting code" have the base class call an abstract method (i.e. must-be-overridden) method that will be supplied by your descendant class.
handle_event() 仍然可以执行“无聊的默认代码”,但不是虚拟的,而是在您希望它执行“新的令人兴奋的代码”时让基类调用抽象方法(即必须覆盖)方法这将由您的后代类提供。
EDIT: And if you later decide that some of your descendant classes do notneed to provide "new exciting code" then you can change the abstract to virtual and supply an empty base class implementation of that "inserted" functionality.
编辑:如果您稍后决定你的一些子类的根本不是需要提供“新的令人兴奋的代码”,那么你可以变抽象到虚拟化和提供一个空基类实现的是“插入”功能。
回答by Mark Ransom
Your compiler may have a warning that it can generate if a base class function becomes hidden. If it does, enable it. That will catch const clashes and differences in parameter lists. Unfortunately this won't uncover a spelling error.
如果基类函数被隐藏,您的编译器可能会发出警告。如果是,请启用它。这将捕获参数列表中的常量冲突和差异。不幸的是,这不会发现拼写错误。
For example, this is warning C4263 in Microsoft Visual C++.
例如,这是 Microsoft Visual C++ 中的警告 C4263。
回答by Adarsh Kumar
C++11 override
keyword when used with the function declaration inside the derived class, it forces the compiler to check that the declared function is actually overriding some base class function. Otherwise, the compiler will throw an error.
C++11override
关键字与派生类中的函数声明一起使用时,它会强制编译器检查声明的函数实际上是否覆盖了某些基类函数。否则,编译器会抛出错误。
Hence you can use override
specifier to ensure dynamic polymorphism (function overriding).
因此,您可以使用override
说明符来确保动态多态性(函数覆盖)。
class derived: public base{
public:
virtual void func_name(int var_name) override {
// statement
}
};