虚函数与回调函数的区别

7
考虑这样一种情况,有两个类,即基类和派生类。如果基类想调用派生类的函数,则可以通过创建一个虚函数并在派生类中定义该VF或使用回调来实现。我想知道在这两个选项中应该选择哪一个?选择其中之一取决于哪些情况/条件?
编辑:问题澄清:
我所指的情况是有一个基类接收消息。这些不同的消息需要由派生类以不同的方式处理,因此一种方法是创建一个虚函数,并让派生类实现它,通过各种开关情况处理每个消息。
另一种方法是通过函数指针(指向派生类函数)在模板内实现回调(模板用于处理派生类对象和函数名称)。模板和函数指针将驻留在基类中。

1
如果您仍在寻找答案,我认为您需要提供一个具体的例子来澄清您的问题。我不明白为什么您需要像选项一那样的“各种开关情况”。通常可以通过程序设计来解决这个问题。在您的第二个选项中,不清楚您所说的模板是什么意思。您是在谈论C++的“模板”,还是某种包含信息以识别函数指针的消息模板?即使是伪代码,也会有所帮助,提供更具体的内容。 - forsvarir
@forsvarir 感谢您的回复,我会在几天后跟进。 - Aquarius_Girl
@forsvarir 对于没有跟进这个话题,我很抱歉。我在几天内回复您,还有其他问题也在等待回答。我完全记得它们,但目前我手头上有太多事情要处理了。我会尽快跟进的。 - Aquarius_Girl
3个回答

6

虚函数调用实际上就是回调。

调用者查找对象虚函数表中对应的条目并调用它。这与回调的行为完全相同,唯一不同的是成员函数指针具有笨拙的语法。虚函数通过将工作卸载给编译器来解决了这个问题,使其成为非常优雅的解决方案。

虚函数是在继承层次结构内部进行通信的方式。


感谢您的回复,但我指的是通过模板实现的C++回调。其次,在特定情况下使用其中之一必定有原因吧? - Aquarius_Girl
3
"callback" 这个术语有些含糊不清。请举一个例子,以便我们可以调整我们的回应(即将其添加到您的问题中)。 - Alexander Gessler
@kgiannakakis,@forsvarir:我已经编辑了问题以获得更多的澄清,如果仍然不清楚,请告诉我。 - Aquarius_Girl

5
我认为这取决于你所说的行为是否属于“Base”知道和子类实现的层次结构。
如果您选择回调解决方案,则回调方法(取决于签名)不必在Base的子类中实现。如果您想要向“事件侦听器”报告“此事件已发生”,并且该侦听器可能在派生类中或者可能在完全不相关的类中,那么这可能是适当的。
如果您选择虚函数解决方案,则更紧密地耦合了Derived和Base类的实现。
一个有趣的阅读材料,可以在某种程度上回答您的问题:Callbacks in C++。它讨论了Functors的用法。另外还有一个在 Wikipedia 上使用模板回调进行排序的示例。您会注意到,回调的实现(它是一个比较函数)不必在执行排序的对象中实现。如果使用虚方法实现,情况则不同。

在我的情况下,基类不知道派生类函数将处理与派生类相关的更改。我会查看你提供的链接,谢谢。 - Aquarius_Girl

2
我认为你所描述的两种情况是不可比较的。虚函数是一种多态工具,帮助你扩展基类以提供额外的功能。它们的关键特征是在运行时决定调用哪个函数。
回调是一个更通用的概念,不仅适用于父子类关系。
因此,如果你想要扩展一个基类,我肯定会选择虚函数。但请确保理解虚函数的工作原理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接