简体   繁体   English

C ++:使用重载而不是动态强制转换通过基数选择派生类

[英]C++: Selecting a Derived Class through a Base Using Overloading instead of Dynamic Cast

As an example to my question, imagine a base class like so: 作为我的问题的一个示例,想象一个像这样的基类:

struct Agent {

    void compete(const Agent& competitor) const = 0;

};

Associated with a derived like this: 与这样的派生关联:

struct RockAgent;
struct PaperAgent;

struct ScissorsAgent: public Agent {

    void compete(const Agent& competitor) const override {
        if(dynamic_cast<const RockAgent*>(&competitor))
            std::cout << "I have lost" << std::endl;

        else if(dynamic_cast<const PaperAgent*>(&competitor))
            std::cout << "I have won!" << std::endl;

        //etc....
    }

};

And compare it to this base: 并将其与此基础:

struct PaperAgent;
struct RockAgent;
struct ScissorsAgent;

struct Agent {

    void compete(const PaperAgent& competitor) const = 0;
    void compete(const RockAgent& competitor) const = 0;
    void compete(const ScissorsAgent& competitor) const = 0;

};

and this derived: 并由此得出:

//forward needed classes.....

struct PaperAgent: public Agent {

    void compete(const PaperAgent& competitor) const override {
        std::cout << "I have won!" << std::endl;
    }

    //etc......

};

If I try to use these two methods by passing to the compete() function an Agent polymorphic instance (reference in this case) only the first one compiles. 如果我试图通过传递给validate()函数来使用这两种方法,那么Agent多态实例(在这种情况下为引用)只会编译第一个。 In the second case, the compiler complains that there is no such function as compete(const Agent&). 在第二种情况下,编译器会抱怨说没有诸如compare(const Agent&)这样的功能。 I understand why this does not work, but is there any alternative out there that does not require dynamic_cast and is closer to the second case showed above in terms of design? 我知道为什么这行不通,但是有没有其他替代方法不需要dynamic_cast,并且在设计方面更接近上面显示的第二种情况? Maybe a design pattern that I'm not aware of, or that I've never imagined could be used to emulate this? 也许我不知道的设计模式,或者我从未想过的设计模式可以用来模仿?

Change Agent : 变更Agent

struct Agent {
  virtual void competeWith(const Agent& competitor) const = 0;
  void compete(const Agent& competitor) const { compeditor.competeWith(*this); }
  virtual void compete(const PaperAgent& competitor) const = 0;
  virtual void compete(const RockAgent& competitor) const = 0;
  virtual void compete(const ScissorsAgent& competitor) const = 0;
};

In PaperAgent: 在PaperAgent中:

struct PaperAgent: public Agent {
  void competeWith(const Agent& competitor) const override final {
    compeditor.compete(*this);
  }
  void compete(const PaperAgent& competitor) const final override;
  void compete(const RockAgent& competitor) const final override;
  void compete(const ScissorsAgent& competitor) const final override;  

}; };

this may be helped with the crtp: crtp可以帮助您:

template<class D>
struct AgentImpl: public Agent 
  void competeWith(const Agent& competitor) const override final {
    compeditor.compete(*static_cast<D const*>(this));
  }
};
struct PaperAgent: public AgentImpl<PaperAgent>{
  void compete(const PaperAgent& competitor) const final override;
  void compete(const RockAgent& competitor) const final override;
  void compete(const ScissorsAgent& competitor) const final override;
};

to reduce code replication. 减少代码复制。

a1.compete(Agent const& a2) invokes a2.competeWith(a1) , which in turn invokes a1.compete(a2) using the dynamic type of a2 and full overload resolution. a1.compete(Agent const& a2)调用a2.competeWith(a1) ,而a1.compete(a2)使用动态类型的a2和完全重载分辨率来调用a1.compete(a2)

This is one of many standard ways to do "double dispatch" -- acting virtually on two arguments at once. 这是执行“双重调度”的许多标准方法之一-几乎同时作用于两个参数。

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

相关问题 C ++如何在不使用static_cast或dynamic_cast的情况下从基类指针访问派生类成员? - C++ How to access derived class member from base class pointer without using a static_cast or dynamic_cast? C ++ dynamic_cast基类指针到派生类指针 - C++ dynamic_cast base class pointer to derived class pointer 用其他派生类C++重载基类的成员函数 - Overloading member function of base class with other derived classes C++ 如何使用 C++ 中的动态转换正确地向下转换基本 class? - How to correctly downcast a base class using dynamic cast in C++? C ++将派生类的成员指针转换为基类指针 - c++ cast member pointer of derived Class to base class pointer C ++:将基类的const引用转换为派生类 - C++: Cast const reference of Base class to derived class C ++&#39;98-将基类转换为派生类 - C++'98 - Cast base class to derived class 将基类指针分配给派生类而不使用动态强制转换 - Assign base class pointer to derived class without using dynamic cast 可以将派生对象转换为c ++模板类中的基本引用吗? - Can derived object cast to base reference in c++ template class? "static_cast 将此对象派生到 C++ 中的基类" - static_cast derived this object to base class in C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM