今天在看文章的时候遇到了multiple dispatch这个术语。看看了wiki,写得云里雾里。最后搜了搜资料,基本上搞清楚了。

multiple dispatch的混淆之处在于其和object system结合在一起。当然wiki上写得很清楚:“a function or method can be dynamically dispatched based on the run time (dynamic) type of more than one of its arguments.”。这摆明了就是和object system紧耦合在了一起。更准确地来讲multiple dispath其实就是专门针对OO中的消息通信的一个概念。与之相关的概念还有single dispatch和dynamic dispatch。

如 果不考虑object system,我觉得function overloading也可以算是一种multiple dispatch。function overloading需要根据参数的类型以及个数来决议调用函数,过程上来讲和multiple dispatch的定义很像,都是通过参数类型来决定调用函数。但是有一个很重要的不同点:multiple dispatch是runtime行为,而function overloading是编译器在compile-time时就决议好了。

要彻底理解multiple dispatch还要从OO的定义说起:OO其实就是对象以及对象间的通信。C++对于对象间的通信采用了函数调用的方式,这与objective-c有点区别。C++的通信方式可以简单地以object.method()的方式呈现。method其实就是信息,object.method()的意思就是method这个信息被派发给了object。这就是所谓有single dispatch,因为信息只能被派发给一个对象。

先举一个简单的例子。有一个状态机S会接受N种不同的trigger,每个trigger要触发当前状态下的一个动作。

class AbstractTrigger;
class AbstractState
{
public:virtual void AcceptTrigger( AbstractTrigger* _trigger ) = 0;
};class AbstractTrigger
{/*....*/
};
class State1 : public AbstractState{public:  void AcceptTrigger( AbstractTrigger* _trigger )  {    /*....*/  }};
class Trigger1 : public AbstractTrigger {   /*....*/ };

目前的难点在于如何根据trigger的类型来选择合适的动作。一种可行的方法是在State1::AcceptTrigger中判断_trigger的实际类型,然后再根据类型去执行相应的动作。这种作法属于过街老鼠式的做法,code review八成是过不去的。另外一种做法是采用visitor pattern的做法,代码如下:

class AbstractTrigger;
class Trigger1;
class AbstractState
{
public:virtual void AcceptTrigger( AbstractTrigger* _trigger ) = 0;virtual void Action1( void ) = 0;
};class AbstractTrigger
{
public:virtual void Action( AbstractState* _state ) = 0;
};class State1 : public AbstractState
{void AcceptTrigger( AbstractTrigger* _trigger ){_trigger->Action }void Action1( void ){/*....*/}
};class Trigger1 : public AbstractTrigger
{
public:void Action( AbstractState* _state ){_state->Action1();}
};

我们在AbstractState中声明了纯虚函数Action1,子类实现它以完成Trigger1时的动作。当然也可以加入Action2, Action3 ... ActionN,分别对应Trigger2, Trigger3 ... TriggerN。在State1::AcceptTrigger中将_trigger派发给了Trigger1,再由Trigger1去调用State1::Action1。之所以整个调用过程做得如此复杂,原因在于State1知道怎么做,但是不知道做哪些;而Trigger1知道做哪些,却不知道怎么做。简言之,在运行时要做哪个动作是由State1和Trigger1两个对象同时决定的,缺一不可。而在C++中一个消息只能同时发给一个对象,在程序需要发消息给多个对象的时候,只能一个一个地去遍历。Lisp有可以把一个消息同时发给多个对象的能力,这种能力就叫做multiple dispatch。

上面的示例代码也可以叫做double dispatch,在wiki上有详细的解释。

参考资料:

  • Multiple Dispatch
  • Multiple Dispatch Wiki

转载于:https://www.cnblogs.com/hughlo/archive/2013/05/28/3100830.html

Multiple Dispatch相关推荐

  1. PyTorch核心开发者灵魂发问:我们怎么越来越像Julia了?

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 梦晨 发自 凹非寺 量子位 报道 | 公众号 QbitAI PyTo ...

  2. 如何设计一门语言(五)——面向对象和消息发送

    面向对象这个抽象的特例总是有说不完的话题,更糟糕的是很多语言都错误地实现了面向对象--class居然可以当一个变量类型什么的这只是让人们写代码写的更糟糕而已.当然这个话题第三篇文章已经说过了,现在来谈 ...

  3. 跟vczh看实例学编译原理——零:序言

    在<如何设计一门语言>里面,我讲了一些语言方面的东西,还有痛快的喷了一些XX粉什么的.不过单纯讲这个也是很无聊的,所以我开了这个<跟vczh看实例学编译原理>系列,意在科普一些 ...

  4. python 数组合并排重_并排深度学习:Julia vs Python

    python 数组合并排重 Julia could possibly be the biggest threat to Python. For a variety of applications, J ...

  5. Julia语言:让高性能科学计算人人可用

    摘要:一群科学家对现有计算工具感到不满:他们想要一套开源系统,有C的快速,Ruby的动态,Python的通用,R般在统计分析上得心应手,Perl的处理字符串处理,Matlab的线性代数运算能力--易学 ...

  6. Redux有何优点?

    by Justin Falcone 贾斯汀·法尔科内(Justin Falcone) Redux有何优点? (What's So Great About Redux?) Redux elegantly ...

  7. Coursera课程 Programming Languages, Part C 总结

    碎言碎语 和前面的 ML 和 Racket 感觉明显不一样了,一边学着一边觉得这真是一门奇怪的语言,有着各种奇怪的语法,不过真的算是一个奇妙的体验(相比前面的两门语言,Ruby 的学习资源多了不少). ...

  8. Java 哪些事最困扰你?

    相信在学Java编程的小伙伴都会遇到很多的问题,特别是当我们写完程序的时候突然报个错,然后找了半天,却没发现哪里报错了,"我在哪","我在干什么"," ...

  9. linux文件夹做链接,linux为什么不能给目录做硬链接

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 issue comes up in language when you switch from single dispatch to multiple d ...

最新文章

  1. 我的LDAP使用手记(Fedora-ds) 备忘用
  2. 深度学习核心技术精讲100篇(五十五)- 基于OpenCV实现棋盘图像识别
  3. 云栖回顾|首届阿里云云原生生态合作伙伴大会:与伙伴能力融合,加速企业数字创新
  4. skywalking链路追踪在微服务架构中的使用
  5. 深入学习consul
  6. 汇编语言(十五)之找出两个数组中的相同元素
  7. html点击弹出iframe,JavaScript:关于跨iframe弹窗
  8. js 提取某()特殊字符串长度
  9. java 删除二维数组中的null_避免在Java中检查Null语句
  10. Arm-Linux 移植 ssh
  11. python标准函数什么意思_python中quote函数是什么意思,怎么用
  12. Unity与Android通信
  13. 2020华为软件精英挑战赛热身赛总结篇
  14. STM32 固件包下载
  15. 2020、2021年FRM一级二级notes
  16. 好货推荐!两款免费的 Linux 桌面录制工具
  17. cachecloud java_【Spring Cloud】Redis缓存接入监控、运维平台CacheCloud
  18. 集成百度做敏感词鉴定
  19. 批量修改MP3文件信息
  20. 图像的拉普拉斯算子之c++实现(qt + 不调包)

热门文章

  1. 04.Python基础_列表_元组_字典_集合
  2. java api 测试工具_Java 实现在线HTTP接口测试 - HTTP GET/POST模拟请求测试工具
  3. 『设计模式』就因为多收了我2块5,我追着收银员问是不是不懂设计模式--策略模式
  4. Floyd —Warshall(最短路及其他用法详解)
  5. Intelij IDEA 常用快捷键
  6. 【个人网盘-updog】使用updog建立个人网盘,so easy
  7. bitnami如何使用_使用Bitnami获取完全配置的Apache Airflow Docker开发堆栈
  8. 专家建议用南方的养老金拿去救济东北,网友炸锅了
  9. 中国房地产市值已经超过450万亿,为何还不见房价下跌?
  10. 我不愿意直接表达情绪:答上海《新闻晨报》记者顾筝小姐问