【发布时间】:2020-12-16 12:55:58
【问题描述】:
假设我有一个名为 Message 的类,其子类为 MessageA、MessageB ... MessageZ。
也许这些消息位于异构队列中,我正在将它们出列,并且我很肯定它们的父类型是 Message,但我只知道这些。
老 C 程序员可能会在 Message 中放置一个字段,该字段基本上是消息类型的枚举,所以我可以这样做:
switch ( message.ActualMessageType ) {
MessageAType:
blah blah A
break;
MessageBType:
blah blah B
break;
:
:
MessageZType:
blah blah Z
break;
}
这很麻烦:当我添加消息子类时,我必须继续编辑那个主枚举定义文件。
对于 C++99,我可能会给 Message 一个名为 BlahBlah() 的纯虚方法,并让每个子类适当地定义它。然后我写的是:
message.BlahBlah();
很好,因为调用虚函数可能比调用 switch 更快(通常实现为跳转查找表,但带有范围检查)。
但是让我们说这个等等等等更干净地属于带有开关的类,而不是那些不需要知道这个特定类如何处理它们的细节的消息。 C++11(或更新的方言?)是否添加了任何有趣的方式来直接跳转到处理各种子消息类型?
例如,如果我调用具有 MessageA 和 MessageB 实现的模板化函数,并带有指向 Message 的指针,其对象实际上是 MessageA 或 MessageB,调用正确的函数吗?
【问题讨论】:
-
不应该调用一个虚函数来做处理吗?
-
虚拟方法是你的朋友。
-
不确定我是否完全理解您试图解决的问题,但您可能想查看visitor pattern 或
std::variant和std::visit。 -
看来您正处于发现
virtual方法的好处的风口浪尖。 -
@SwissFrank - 由实例化消息类的实体来附加处理程序。当您使消息出队时,您将调用处理程序。也许您无法控制消息类的创建,在这种情况下这是不可行的。使用附加函数的好处之一是,如果这样做有好处,可以在运行时更改它们。也就是说,您可以拥有一些处理程序,并根据需要将它们附加到不同的消息类,即使在运行时也是如此。
标签: c++ polymorphism rtti