Double dispatch/multimethods in C++

前端 未结 4 1490
无人及你
无人及你 2020-12-03 12:21

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.

I don\'t know the actua

4条回答
  •  攒了一身酷
    2020-12-03 12:31

    You'll have to put a virtual method on BaseClass to call processObj from the derived classes.

    class BaseClass{
    public:
           BaseClass(){}
           virtual void ProcessThis(Processor &p) { p.processObj(this); }
           virtual void myFunction(){cout << "base myFunction called" << endl;}
    };
    
    class Derived1: public BaseClass{
    public:
           Derived1():BaseClass(){}
           void ProcessThis(Processor &p) { p.processObj(this); }
           void myFunction(){cout << "Derived1 myFunction called" << endl;}
    };
    
    class Derived2: public BaseClass{
    public:
           Derived2():BaseClass(){}
           void ProcessThis(Processor &p) { p.processObj(this); }
           void myFunction(){cout << "Derived2 myFunction called" << endl;}
    };
    
    class Derived3: public BaseClass{
    public:
           Derived3():BaseClass(){}
           void ProcessThis(Processor &p) { p.processObj(this); }
           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
       bcp->ProcessThis(p);
       dc1p->ProcessThis(p);
       dc1p->ProcessThis(p);
       dc3p->ProcessThis(p);
    
       BaseClass *bcp1=bcp;
       BaseClass *dc1p1=dc1p;   
       BaseClass *dc2p1=dc2p;
       BaseClass *dc3p1=dc3p;
    
       //second set results
       bcp1->ProcessThis(p);
       dc1p1->ProcessThis(p);
       dc2p1->ProcessThis(p);
       dc3p1->ProcessThis(p);
    
       Processor p2;
       bcp1->ProcessThis(p2);
       dc1p1->ProcessThis(p2);
       dc2p1->ProcessThis(p2);
       dc3p1->ProcessThis(p2);
    
       return 0;
    }
    

    You basically want the Visitor pattern, but with only one type of visitor. You might save yourself some future effort and make Processor into an abstract class and implement the one concrete ProcessorImpl class, making it trivial to add another processor class in the future, or you could wait until that situation comes up and leave things as is for now.

提交回复
热议问题