Double Dispatch手法

原创
2016/05/07 18:42
阅读数 316

首先要明白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;
}


展开阅读全文
2
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
2
分享
返回顶部
顶部