madx
madx

Reputation: 7203

Override of the same function with inherited class

I have this simple code:

#include <iostream>
using namespace std;

class GenericMove {};

class SwapMove: public GenericMove {};

class SoftConstraint {
  public:
    virtual int evaluate(GenericMove& gm) = 0;
};

class M1: public SoftConstraint {
  public:
    int evaluate(GenericMove& gm){ return 1; }
    int evaluate(SwapMove& gm){ return 2; }
};

int main () {
  M1 m1;
  GenericMove* swapmove = new SwapMove();
  cout << "Hello " << m1.evaluate(*swapmove) << endl;
  return 0;
}

I would like to discern between GenericMove and SwapMove in the evaluate function of M1 , so I would like that the main prints "Hello 2".

Is there a way to distinguish that swapmove is not only a simple GenericMove but it is also SwapMove inside M1?

Is that possible in C++? Thanks in advance!

Upvotes: 0

Views: 49

Answers (1)

Kristian Duske
Kristian Duske

Reputation: 1779

No, this is not directly possible in C++ AFAIK, but you can use double dispatch to achieve your desired result.

class GenericMove;
class SwapMove;

class SoftConstraint {
public:
    virtual int evaluate(GenericMove& move) = 0;
    virtual int evaluate(SwapMove& move) = 0;
};

class M1 : public SoftConstraint {
public:
    int evaluate(GenericMove& move) { return 1; }
    int evaluate(SwapMove& move) { return 2; }
};

class GenericMove {
public:
    virtual int evaluate(SoftConstraint& constraint) {
        return constraint.evaluate(*this);
    }
};

class SwapMove : public GenericMove {
public:
    int evaluate(SoftConstraint& constraint) {
        return constraint.evaluate(*this);
    }   
};

int main () {
  M1 m1;
  GenericMove* swapmove = new SwapMove();
  std::cout << "Hello " << swapmove->evaluate(m1) << std::endl;
  return 0;
}

Note that in my proposal you have to call the evaluate method of the move instance as opposed to calling the evaluate method of the constraint. But this could be changed easily.

Double dispatch exploits the fact that the static type of the this pointer is always the type to which the function using the this pointer belongs. In our example, the static type of this in GenericMove::evaluate is GenericMove* , so the call to SoftConstraint::evaluate selects the function that takes a reference to an instance of GenericMove as its argument. On the other hand, the static type of this in SwapMove::evaluate is SwapMove* , so the call to SoftConstraint::evaluate selects the function that takes a reference to an instance of SwapMove as its argument.

Double dispatch allows you to select a method using the type of the receiver of the call and the type of one argument.

Upvotes: 1

Related Questions