Double Dispatch手法
首先要明白Dispatch 是什么
多态的实现,是通过一个虚表 达到运行时决策,真正调用的 为真正的对象来决定,这叫做一次 dispatch (实现一次多态的 动态决定)
Double dispatch 应用 在什么地方呢?,其中设计模式中的Visitor 就是一种实现
Visitor模式连接 http://my.oschina.net/kkkkkkkkkkkkk/blog/670610
先看以下代码的问题
class Monster; class FlyMonster; class WalkMonster; class MonsterMgr { public: void Add(Monster*monster) { cout << "Monster" << endl; } void Add(FlyMonster*fly) { cout << "fly" << endl; } void Add(WalkMonster*walk) { cout << "walk" << endl; } }; class Monster { public: }; class FlyMonster:public Monster { public: }; class WalkMonster :public Monster { public: }; int main(int argc, char *argv[]) { Monster *monster = new FlyMonster; MonsterMgr *mgr = new MonsterMgr; mgr->Add(monster); system("pause"); return 0; }
由于Add 有多个重载版本,重载编译时就确定了,因为变量monster 声明类型为Monster 所以调用的是Monster版本的 Add,并不是期望的FlyMonster版本
所以我们要再添加一次dispatch达到目的,
原本设计是Mgr 添加怪物,现在改为怪物吧自己添加到Mgr里面,达到再次Dispatch。 从而达到期望的调用Fly 版本的Add,子类的this才是真正的运行时期对象。
给我的感觉是这种设计更像是反向,C++ 不支持的double dispatch 就可以通过这样解决
class Monster; class FlyMonster; class WalkMonster; class MonsterMgr { public: void Add(Monster*monster) { cout << "Monster" << endl; } void Add(FlyMonster*fly) { cout << "fly" << endl; } void Add(WalkMonster*walk) { cout << "walk" << endl; } }; class Monster { public: virtual void AddToMgr(MonsterMgr*m) { m->Add(this); } }; class FlyMonster:public Monster { public: virtual void AddToMgr(MonsterMgr*m) { m->Add(this); } }; class WalkMonster :public Monster { public: virtual void AddToMgr(MonsterMgr*m) { m->Add(this); } }; int main(int argc, char *argv[]) { Monster *monster = new FlyMonster; MonsterMgr *mgr = new MonsterMgr; monster->AddToMgr(mgr); system("pause"); return 0; }