首页 > 解决方案 > 在 C++ 中实现双重调度的问题

问题描述

感谢您花时间看我的问题。我正在尝试在 C++ 中实现双重调度,但它似乎没有采取。我想我可能缺少一些东西?我不相信对象切片是我使用指针的问题。我已经阅读过有关重载解决方案的问题,而双重调度是一种解决方法。任何帮助表示赞赏。

这是我的代码

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;
}

我希望输出是

Visited unknown reactor
Visited ideal reactor

但相反我得到

Base
Base

打电话时doubleDispatchExample()

有人建议我将功能设为虚拟,这给了我

Visited unknown reactor
Visited unknown reactor

标签: c++oopoverloading

解决方案


我发现这ConditionerBase两个类都需要重载函数,它给了我想要的输出。将其更改为以下给出了我想要的输出。

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;
}

推荐阅读