考虑一个场景,其中有两个类,即Base和Derived。如果Base类想要调用派生类的函数,它可以通过创建虚函数并在派生类中定义该VF或使用回调来实现。 。我想知道两者应该优先考虑什么?选择两者取决于哪些情况/条件?
修改 的 问题澄清:
我指的是有一个接收消息的基类。这些不同的消息将由派生类以不同方式处理,因此一种方法是创建虚函数并让派生类实现它,通过各种切换案例处理每条消息。
另一种方法是通过模板内部的函数指针(指向派生类的函数)实现回调(处理派生类的对象和函数名称需要模板)。模板和函数指针将驻留在基类中。
答案 0 :(得分:4)
虚拟函数调用实际上是回调。
调用者在对象的虚函数表中查找相应的条目并调用它。这与回调行为完全相同,只是成员函数指针具有笨拙的语法。虚函数将工作卸载到编译器,这使它们成为一个非常优雅的解决方案。
虚函数是继承层次结构中的通信方式。
答案 1 :(得分:4)
我认为这归结于一个决定,即你所谈论的行为是否属于“基地”知道和儿童实施的层次结构。
如果你使用回调解决方案,那么回调方法(取决于签名)不必在Base的子节点中实现。这可能是合适的,例如,如果您想对可能在派生类中的'事件侦听器'说'此事件已经发生',或者可能在一个完全不相关的类中,恰好对该事件感兴趣。
如果你使用虚函数解决方案,那么你就可以更紧密地结合Derived和Base类的实现。
一个有趣的读物,可能会在某种程度上回答你的问题:Callbacks in C++讨论Functors的用法。 Wikipedia上还有一个使用模板回调进行排序的示例。您会注意到回调的实现(比较函数)不必在执行排序的对象中。如果它是使用虚方法实现的,那就不是这种情况了。
答案 2 :(得分:1)
我不认为你所描述的两个案例具有可比性。虚函数是一种多态性工具,可帮助您扩展基类以提供其他功能。它们的关键特征是决定调用哪个函数是在运行时进行的。
回调是一个更通用的概念,它不仅适用于父子类关系。
因此,如果您想要扩展基类,我肯定会使用虚函数。但请务必了解虚拟功能的工作原理。