实在不想在此处用switch…请教各位有没有其他替代品?

gamemagic 2011-04-15 08:54:09
void MyClass::DispatchMessage(Message & msg)
{

Message是一个“消息参数”基类,其派生出“键盘消息” “鼠标消息”等类,

而当外部调用这个函数时,我不得不这样写,才知道传入了哪个参数:
switch(msg.MessageID)
{
case MID_KEYBOARD:
DispatchMessage(dynamic_cast<KeyboardMsg&>(msg));
………

请问有没有不用switch的办法?
...全文
687 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2013-03-18
  • 打赏
  • 举报
回复
恩,switch 结构还是蛮清晰的,如果处理的消息不多。事实上处理的消息也并没有多少,WM_KEYXXX,WM_MOUSEXXX。 利用函数指针或者多态也是一种解决办法,问题在于,你的设计为何要将所有的消息处理实现代码放在一个函数中进行? 比如一个DX的GUI库,响应鼠标点击事件,消息传递是逐层传递进去的,最终到某个控件,那么该控件需要关心的,也就不多了。
pathuang68 2011-04-17
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 gamemagic 的回复:]

算了,我还是用多态吧

这才是最优雅的办法。编译期就能直接绑定对应的函数
[/Quote]

多态是运行时绑定哦,不要搞错了。
lxq301872 2011-04-16
  • 打赏
  • 举报
回复
还是switch好一些吧
天上游的鱼 2011-04-16
  • 打赏
  • 举报
回复
直接用多态吧,试下 DispatchMessage 通过虚函数实现
失落的凡凡 2011-04-16
  • 打赏
  • 举报
回复
switch与if…else…的性能差异的临界点肯定比10个低的多。而且,编译器认为switch性能不如if…else…的时候,会自动优化成if…else…的。
pathuang68 2011-04-16
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 arong1234 的回复:]

实际上MFC就是用跳转表(微软叫它消息映射)做到的
[/Quote]

嗯,但消息映射表通常不是很大。

如果没有记错,微软自己在SDK中处理消息是用switch...case...的
pathuang68 2011-04-16
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 arong1234 的回复:]

为什么为每个消息增加一个函数会降低可维护性?低粒度的代码(也就是每个消息一个小函数而不是所有消息都放一个函数)可以极大地降低修改造成bug的可能性,是应该提高可维护性的
引用 13 楼 pathuang68 的回复:
引用 10 楼 gamemagic 的回复:

用“函数指针列表”如何?

typedef void (MyClass::*PFN)(Message &amp;……
[/Quote]

我觉得还需要看具体情况。
比如,那如果每个函数一行代码或几行代码,粒度就差不多最低了,你觉得这样的代码可维护性差不多最高吗?

当仍然这个例子有点极端。但也说明,在这方面没有什么固定的原则,一切还是要根据实际情况来定。
pathuang68 2011-04-16
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hpsmouse 的回复:]

于是我邪恶地想起了《Modern C++ Design》里面的 dispatcher……
C/C++ code
#include <typeinfo>
#include <map>
#include <iostream>

class TypeInfoWarpper
{
public:
TypeInfoWarpper(std::type_info const &……
[/Quote]

代码很优雅,但效率肯定不如switch...case...
  • 打赏
  • 举报
回复
枚举。。C++ 有没有,我是C#的
arong1234 2011-04-16
  • 打赏
  • 举报
回复
实际上MFC就是用跳转表(微软叫它消息映射)做到的
arong1234 2011-04-16
  • 打赏
  • 举报
回复
为什么为每个消息增加一个函数会降低可维护性?低粒度的代码(也就是每个消息一个小函数而不是所有消息都放一个函数)可以极大地降低修改造成bug的可能性,是应该提高可维护性的
[Quote=引用 13 楼 pathuang68 的回复:]
引用 10 楼 gamemagic 的回复:

用“函数指针列表”如何?

typedef void (MyClass::*PFN)(Message &amp;msg);

PFN pfn[30];
……
this->*pfn[msg.MessageID](msg);

这个想法很好:)但代价是要针对每一种消息都要定义一个专门的处理函数,也会在一定程度上降低代码的可维护……
[/Quote]
太乙 2011-04-16
  • 打赏
  • 举报
回复
这个不就是select/poll/epoll的问题么?
Defonds 2011-04-16
  • 打赏
  • 举报
回复
switch 还是很不错的
itslmde 2011-04-16
  • 打赏
  • 举报
回复
说白了,程序员只是不喜欢做技术含量比较低的事罢了,比如硬性的添加 case 分支。
然后想方设法的花大量时间去琢磨一个看上去更加优雅,更易维护其实却更加复杂的技术。
蔡袅 2011-04-16
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 loaden 的回复:]
10个以上用switch性能好,10个以下用if/else if/else if...
[/Quote] 确定吗?确定则学习。
itslmde 2011-04-16
  • 打赏
  • 举报
回复
哪种简单就用哪种呗,很多看上去优雅的方法,其背后体现的复杂性也可能更难维护。
huer0625 2011-04-16
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 pathuang68 的回复:]
引用 10 楼 gamemagic 的回复:

用“函数指针列表”如何?

typedef void (MyClass::*PFN)(Message &amp;msg);

PFN pfn[30];
……
this->*pfn[msg.MessageID](msg);

这个想法很好:)但代价是要针对每一种消息都要定义一个专门的处理函数,也会在一定程度上降低代码的可维护……
[/Quote]
++1
crjwlaq 2011-04-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 pathuang68 的回复:]

引用 6 楼 gamemagic 的回复:

不知道能不能通过C++的重载等特性,用什么技巧把它给去掉?

因为将陆续添加各种不同的基于Message的参数,不想维护一个超长的switch代码块

我C++很烂…

用设计模式(通常意义上的设计模式,如GoF提出的那23种)肯定可以做到连if...else都没有(部分设计模式狂热分子,甚至说要用设计模式消灭if...else,这自……
[/Quote]

学习了
gamemagic 2011-04-16
  • 打赏
  • 举报
回复
算了,我还是用多态吧

这才是最优雅的办法。编译期就能直接绑定对应的函数
qq120848369 2011-04-16
  • 打赏
  • 举报
回复
说白了就是做个信息类型到处理函数的哈希,处理函数可以利用设计模式抽象出基类.
加载更多回复(22)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧