在C ++中的双调度/多方法 [英] Double dispatch/multimethods in C++

查看:120
本文介绍了在C ++中的双调度/多方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于C ++双调度的问题。在下面的代码中,我想让第二个集合的结果匹配第一个集合的结果。

I have a question on C++ double dispatch. In the code below, I want the results from the second set to match the results from the first set.

我不知道实际类型(除非我尝试dynamic_cast),但我知道对象继承自BaseClass类型。

I don't know the actual type (unless I try dynamic_cast) but I do know that the object inherited from the BaseClass type. What is the most efficient (performance-wise) way to accomplish this?

在搜索一段时间后,我发现了双调度和loki多方法。我使用Shape示例的问题是,在我的应用程序,Processor和BaseClass是完全独立的,没有一个通用的方法,他们可以调用对方。第二,只有一个处理器(即没有继承它)。

After googling around for a while I found out about double dispatch and the loki multimethods. The problem I have with the Shape examples is that in my application, Processor and BaseClass are entirely independent and don't have a common method that they can call in each other. Secondly, there is only one Processor (i.e. nothing inherits from it).

感谢任何帮助。

#include <iostream>
#include <string>
using namespace std;

class BaseClass{
public:
       BaseClass(){}
       virtual void myFunction(){cout << "base myFunction called" << endl;}
};

class Derived1: public BaseClass{
public:
       Derived1():BaseClass(){}
       void myFunction(){cout << "Derived1 myFunction called" << endl;}
};


class Derived2: public BaseClass{
public:
       Derived2():BaseClass(){}
       void myFunction(){cout << "Derived2 myFunction called" << endl;}
};

class Derived3: public BaseClass{
public:
       Derived3():BaseClass(){}
       void myFunction(){cout << "Derived3 myFunction called" << endl;}

};

class Processor{
public:
       Processor(){}
       virtual void processObj(BaseClass* bc){cout << "got a base object" << endl; bc->myFunction();}
       virtual void processObj(Derived1* d1){cout << "got a derived1 object" << endl; d1->myFunction();}
       virtual void processObj(Derived2* d2){cout << "got a derived2 object" << endl; d2->myFunction(); }
};


int main() {
   BaseClass *bcp=new BaseClass();
   Derived1 *dc1p=new Derived1();   
   Derived2 *dc2p=new Derived2();
   Derived3 *dc3p=new Derived3();

   Processor p;//can also use Processor* p = new Processor()

   //first set results
   p.processObj(bcp);
   p.processObj(dc1p);
   p.processObj(dc2p);
   p.processObj(dc3p);

   BaseClass *bcp1=bcp;
   BaseClass *dc1p1=dc1p;   
   BaseClass *dc2p1=dc2p;
   BaseClass *dc3p1=dc3p;

   //second set results
   p.processObj(bcp1);
   p.processObj(dc1p1);
   p.processObj(dc2p1);
   p.processObj(dc3p1);

   return 0;
}


推荐答案

此模式的要点是确保调用处理器的正确方法 - 接受正确类型的方法。由于处理器最初不知道传递给它的对象的类型,您需要 对象告诉处理器它是什么类型。

The point of this pattern is to make sure that the right method of the processor is called - the method that accepts the right type. Since the processor is initially not aware of the type of the object that's passed to it, you need the object to tell the processor what its type is.

实质上,每个对象需要一个虚拟的processMe(Processor& p)方法,并且处理器调用它。 processMe的实现调用p.processObject(this)。但这一次,这个有已知的类型!所以代替无限递归,你最终得到了正确的procedessObj,称为

In essence, each object needs a virtual "processMe(Processor &p)" method, and the processor calls it. The implementation of processMe calls p.processObject(this). But this time around, "this" has the known type! So instead of infinite recursion, you end up with the right proceessObj called

这篇关于在C ++中的双调度/多方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆