问题描述
说我有一个名为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();
很好,因为调用一个虚函数可能比开关要快(通常实现为跳转的查找表,但具有范围检查功能)。
但是,可以说,这个等等更明确地属于带有开关的类,而不是不需要知道特定类如何处理它们的消息的消息。 C ++ 11(或更新的方言?)是否添加了任何有趣的方式直接跳转到处理各种子消息类型?
例如,如果我调用一个模板化函数,该函数具有MessageA和MessageB的实现,并带有指向Message(其对象实际上是MessageA或MessageB的对象)的指针,则调用正确的函数?
解决方法
我认为可能有更好的解决方案,但这是C ++ 99解决方案。
Message
类具有纯虚方法BlahBlah( Processor* )
。
原本需要switch语句的Processor
将具有名为BlahBlahA( MessageA* pmsga )
,BlahBlahB( MessageB* pmsgb )
,... BlahBlahZ( MessageZ* pmsgz )
的方法,这些方法采用指向所涉及消息类型的指针
子类MessageA
将定义:
virtual void BlahBlah( Processor* pproc ) { pproc->BlahBlahA( this ); };
Processor
类要执行特定于消息类的处理时,将调用:
pmsg->BlahBlah( this );
这将调用BlahBlah()
的每个子类定义,该定义将在Processor
类上调用相应的方法。
好处:
- 无需维护全局枚举
- 所有处理代码都在Processor中,而不在Message子类中
- 无需切换。
- 不需要强制转换,RTTI等
缺点:
- 两个虚拟函数调用会带来某种开销。