2011-04-06 113 views
4

考虑一个场景,其中有两个类,即Base和Derived。如果基类要调用派生类的函数,则可以通过创建虚拟函数并在派生类中定义该VF或使用回调来实现。我想知道两者中应该选择哪一个?两者之间的选择取决于哪些情况/条件?虚拟功能与回调

编辑: 问题澄清:

我指的是所述的情况是,有其接收消息的基类。这些不同的消息将由派生类以不同方式处理,所以一种方法是创建一个虚拟函数并让派生类实现它,通过各种开关情况处理每条消息。

另一种方法是通过模板内部的函数指针(指向派生类的函数)实现回调(需要模板来处理派生类和函数名称的对象)。模板和函数指针将驻留在基类中。

+1

我想你需要提供一个具体的例子来澄清你的问题,如果你仍然在寻找答案。我不明白你为什么需要'各种开关盒',例如选项一。通过程序设计通常有这样的方法。在第二种选择中,您不清楚模板的含义。你是在谈论C++'templates'还是某种包含信息来识别函数指针的消息模板?更具体的东西,即使它是伪代码也是有帮助的。 – forsvarir 2011-05-24 11:42:39

+0

@forsvarir感谢您的回复,我会在几天后跟进。 – 2011-05-24 11:51:15

+0

@forsvarir请原谅我不跟进这个话题。我***会在几天内回到这个问题,还有其他一些问题。我完全记得它们,但是现在我的碟子上有太多菜。将很快跟进。 – 2012-04-05 07:15:17

回答

4

虚拟函数调用实际上是一个回调函数

调用者在对象的虚函数表中查找对应的条目并调用它。这就像一个回调的行为,除了成员函数指针具有尴尬的语法。虚拟功能将工作卸载到编译器,这使得它成为一个非常优雅的解决方案。

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

+0

感谢您的回复,但我指的是通过模板实现的C++回调。其次,在特定情况下,两者中的任何一个都是首选的原因肯定是有原因的? – 2011-04-06 10:23:04

+3

术语回调有点模糊。请举一个例子,我们可以微调我们的反应(即将其添加到您的问题中) – 2011-04-06 10:24:39

+0

@kgiannakakis,@forsvarir:我已编辑该问题以获得更多解释,如果仍不清楚,请告诉我。 – 2011-04-13 06:36:22

4

我认为这取决于您所谈论的行为是否属于'Base'知道的关于儿童实施的层次。

如果使用回调解决方案,则回调方法(取决于签名)不必在Base的子项中实现。例如,如果您想对可能在派生类中的“事件侦听器”说'此事件已经发生',或者可能处于恰好对该事件感兴趣的完全不相关的类中,这可能是合适的。

如果您使用虚拟功能解决方案,那么您将更紧密地耦合Derived和Base类的实现。

一个有趣的阅读,可能会回答你的问题的某种方式是:Callbacks in C++其中谈论的Functors的用法。 Wikipedia也有一个使用模板回调进行排序的示例。您会注意到回调(这是一个比较函数)的实现不必位于执行排序的对象中。如果它是使用虚拟方法实现的,则情况并非如此。

+0

在我的情况下,基类不知道将要处理派生类的变化的派生类函数。我会看看你的链接,谢谢。 – 2011-04-13 06:38:33

1

我不认为你描述的两种情况是可比的。虚拟函数是一种多态工具,可帮助您扩展基类以提供附加功能。它们的关键特征是在运行时决定哪个函数被调用。

回调是一个更一般的概念,它不仅适用于父子关系。所以,如果你想要做的事涉及扩展基类,我肯定会去虚拟功能。请确保了解虚拟功能的工作原理。