简体   繁体   English

在 C++ 中实现双重调度的问题

[英]Issues implementing double dispatch in C++

Thanks for taking the time to look at my question.感谢您花时间看我的问题。 I am trying to implement double dispatch in C++ but It doesn't seem to be taking.我正在尝试在 C++ 中实现双重调度,但它似乎没有采取。 I suppose there may be something that I am missing?我想我可能缺少一些东西? I don't believe object slicing is the issue as I am using pointers.我不相信 object 切片是我使用指针的问题。 I have read about issues with overload resolution and that double dispatch was a way around that.我已经阅读过有关重载解决方案的问题,而双重调度是一种解决方法。 Any help is appreciated.任何帮助表示赞赏。

Here is my code这是我的代码

class ReactType;
class ConditionerBase
  {
  public:
    ConditionerBase(/* args */){};
    ~ConditionerBase(){};
    virtual void visit(ReactType* reactor);
  };

  class ReactType
  {
  public:
    ReactType(/* args */){};
    ~ReactType(){};
    virtual void accept(ConditionerBase *conditioner);
  };
  
  class IdealReactType: public ReactType
  {
  public:
    IdealReactType(/* args */){};
    ~IdealReactType(){};
    virtual void accept(ConditionerBase *conditioner);
  };

  class Conditioner : public ConditionerBase
  {
  public:
    Conditioner(/* args */){};
    ~Conditioner(){};
    virtual void visit(ReactType* reactor){std::cout<<"Visited unknown reactor"<<std::endl;};
    virtual void visit(IdealReactType* ideal_reactor){std::cout<<"Visited ideal_reactor"<<std::endl;};
  };

  void ReactType::accept(ConditionerBase *conditioner){conditioner->visit(this);};
  void IdealReactType::accept(ConditionerBase *conditioner){conditioner->visit(this);};
  void ConditionerBase::visit(ReactType* reactor){std::cout<<"Base"<<std::endl;};

void doubleDispatchExample()
{

  std::vector<ReactType*> reactors;
  ReactType* unknown = new ReactType();
  IdealReactType* ideal_reactor = new IdealReactType();
  reactors.push_back(unknown);
  reactors.push_back(ideal_reactor);
  Conditioner conditioner;
  for (size_t i = 0; i < 2; i++)
  {
    reactors.at(i)->accept(&conditioner);
  }
  delete unknown;
  delete ideal_reactor;
}

I want the output to be我希望 output 成为

Visited unknown reactor
Visited ideal reactor

but instead I get但相反我得到

Base
Base

when calling doubleDispatchExample()当调用doubleDispatchExample()

It was suggested that I make the functions virtual which gives me有人建议我将功能设为虚拟,这给了我

Visited unknown reactor
Visited unknown reactor

I found out that the ConditionerBase needs both classes of the overloaded functions and it gives me the desired output.我发现ConditionerBase需要这两个类的重载函数,它给了我想要的 output。 Changing it to the following gives the output I want.将其更改为以下给出了我想要的 output。

class ReactType;
class IdealReactType;
class ConditionerBase
  {
  public:
    ConditionerBase(/* args */){};
    ~ConditionerBase(){};
    virtual void visit(ReactType* reactor);
    virtual void visit(IdealReactType* reactor);
  };

  class ReactType
  {
  public:
    ReactType(/* args */){};
    ~ReactType(){};
    virtual void accept(ConditionerBase *conditioner);
  };
  
  class IdealReactType: public ReactType
  {
  public:
    IdealReactType(/* args */){};
    ~IdealReactType(){};
    virtual void accept(ConditionerBase *conditioner);
  };

  class Conditioner : public ConditionerBase
  {
  public:
    Conditioner(/* args */){};
    ~Conditioner(){};
    virtual void visit(ReactType* reactor){std::cout<<"Visited unknown reactor"<<std::endl;};
    virtual void visit(IdealReactType* ideal_reactor){std::cout<<"Visited ideal_reactor"<<std::endl;};
  };

  void ReactType::accept(ConditionerBase *conditioner){conditioner->visit(this);};
  void IdealReactType::accept(ConditionerBase *conditioner){conditioner->visit(this);};
  void ConditionerBase::visit(ReactType* reactor){std::cout<<"Base Reactor"<<std::endl;};
  void ConditionerBase::visit(IdealReactType* reactor){std::cout<<"Base Ideal"<<std::endl;};

void doubleDispatchExample()
{

  std::vector<ReactType*> reactors;
  ReactType* unknown = new ReactType();
  IdealReactType* ideal_reactor = new IdealReactType();
  reactors.push_back(unknown);
  reactors.push_back(ideal_reactor);
  Conditioner conditioner;
  for (size_t i = 0; i < 2; i++)
  {
    reactors.at(i)->accept(&conditioner);
  }
  delete unknown;
  delete ideal_reactor;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM