虚拟函数与回调
考虑有两个类的场景,即 Base 类和 Derived 类。如果基类想要调用派生类的函数,它可以通过创建一个虚拟函数并在派生类中定义该 VF 或使用回调来实现。我想知道这两者应该优先选择哪个?两者之间的选择取决于哪种情况/条件?
编辑: 问题澄清:
我指的情况是有一个接收消息的基类。这些不同的消息将由派生类以不同的方式处理,因此一种方法是创建一个虚函数并让派生类实现它,通过各种 switch case 处理每个消息。
另一种方法是通过模板内的函数指针(指向派生类的函数)来实现回调(模板需要处理派生类的对象和函数名)。模板和函数指针将驻留在基类中。
Consider a scenario where there are two classes i.e. Base and Derived. If the Base class wants to call a function of the derived class, it can do so by either making a virtual function and defining that VF in the derived class or by using callbacks. I want to know in what should be preferred out of the two? Choosing among the two depends on which situations/conditions?
EDIT:
Question Clarification:
The situation I was referring to is that there is a base class which receives messages. These different messages are to be handled differently by the derived class, so one way is to create a virtual function and let the derived class implement it, handling every message though various switch cases.
Another way is to implement the callbacks through the function pointers (pointing to the functions of derived class) inside the templates (templates are needed for handling the object of the derived class and the function names). The templates and the function pointers are going to reside in the base class.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
虚拟函数调用实际上是一个回调。
调用者在对象的虚函数表中查找相应的条目并调用它。这与回调的行为完全一样,只是成员函数指针的语法很尴尬。虚函数将工作卸载给编译器,这使它们成为一个非常优雅的解决方案。
虚函数是继承层次结构中进行通信的方式。
A virtual function call is actually a callback.
The caller looks up the corresponding entry in the object's virtual function table and calls it. That's exactly like a callback behaves, except that member function pointers have awkward syntax. Virtual functions offload the work to the compiler, which makes them a very elegant solution.
Virtual functions are the way to communicate within the inheritance hierarchy.
我认为这取决于您所讨论的行为是否属于“Base”知道且子实现的继承体系中的决定。
如果您采用回调解决方案,则回调方法(取决于签名)不必在 Base 的子级中实现。例如,如果您想对可能位于派生类中的“事件侦听器”说“此事件已发生”,或者可能位于恰好对该事件感兴趣的完全不相关的类中,则这可能是合适的。
如果您采用虚函数解决方案,那么您将更紧密地耦合派生类和基类的实现。
一个有趣的读物,可能会在某种程度上回答您的问题:Callbacks in C++ 其中谈论 Functor 的用法。 Wikipedia 上还有一个使用模板回调进行排序的示例。您会注意到回调(这是一个比较函数)的实现不必位于执行排序的对象中。如果使用虚拟方法来实现,情况就不会如此。
I think this comes down to a decision about whether or not the behaviour you're talking about is something that belongs in the heirarchy that 'Base' knows about and child implements.
If you go with a callback solution, then the callback method (depending on signature) doesn't have to be implemented in a child of Base. This may be appropriate if for example you wanted to say 'this event has happened' to an 'event listener' that could be in a derived class, or could be in a totally unrelated class that happens to be interested in the event.
If you go with the virtual function solution, then you're more tightly coupling the implentation of the Derived and Base classes.
An interesting read, which may go some way to answering your question is: Callbacks in C++ which talks about the usage of Functors. There's also an example on Wikipedia that uses a template callback for sorting. You'll notice that the implementation for the callback (which is a comparison function) does not have to be in the object that is performing the sort. If it were implemented using virtual methods, this wouldn't be the case.
我认为你所描述的两个案例没有可比性。虚函数是一种多态性工具,可帮助您扩展基类以提供附加功能。它们的关键特征是调用哪个函数的决定是在运行时做出的。
回调是一个更通用的概念,不仅仅适用于父子类关系。
因此,如果您想做涉及扩展基类,我肯定会选择虚函数。但请务必了解虚拟函数的工作原理。
I don't think that the two cases you are describing are comparable. Virtual functions are a polymorphism tool that aid you in extending a base class in order to provide additional functionality. The key characteristic of them is that the decision which function will be called is made in runtime.
Callbacks are a more general concept, that doesn't apply only on a Parent-Child class relationship.
So, if you want to do involves extending a base class, I would certainly go with virtual functions. Be sure however to understand how virtual functions work.