views:

576

answers:

4

I'm trying to override Object::Equals in C++ .NET but I'm running into some difficulties

virtual bool IState::Equals(Object^ o) override{
     if (o->GetType() == IState::typeid){
      IState^ s = (IState^) o;
      if (s->type == this->type &&
       s->target_state == this->target_state &&
       s->current_state == this->current_state){
       return true;
      }
      else{
       return false;
      }
     }
     return false;
    }

This code works fine if o is and IState. However, I inherit from IState with State. I'd like my Equals function to return true if I pass a State with the same content.

I get that State is not the same as IState, but is there an operator which will allow me to check if they inherit from the same base class? Maybe overloading the operator typeid might help, but it seems like a lot of trouble for that

A: 

How about using the typeid operator? http://msdn.microsoft.com/en-us/library/fyf39xec(VS.80).aspx

Tamar
This is basically what I do. If I use the typeid() then the compiler tells me to use the ::typeid syntax with error c3185http://msdn.microsoft.com/en-us/library/sf08zfcc.aspx
Eric
+2  A: 

Is using reflection an option? If so, take a look at the Type::IsAssignableFrom() method, and the Type::BaseType property.

Steve Guidi
A: 

Ok I managed to get it to work

I was missing the ->BaseType() after the ->GetType()

here is the working version

virtual bool IState::Equals(Object^ o) override{
        if (o->GetType()->BaseType() == IState::typeid){
                IState^ s = (IState^) o;
                if (s->type == this->type &&
                        s->target_state == this->target_state &&
                        s->current_state == this->current_state){
                        return true;
                }
                else{
                        return false;
                }
        }
        return false;
    }

thank you all for your time, support and devotion =)

Eric
This will still break if you add one more inheritance level; i.e. IState <- Foo <- Bar, and then pass an instance of Bar to your IState::Equals().
Pavel Minaev
+1  A: 

The correct way to do this is to use dynamic_cast, and check for nullptr:

virtual bool IState::Equals(Object^ o) override {
    IState^ s = dynamic_cast<IState^>(o);
    if (s != nullptr) {
        ...
    }
    return false;
}

C-style cast (avoid those BTW) that you have used will actually do a safe_cast, which throws InvalidCastException on failure, so you have to spell out dynamic_cast explicitly.

Pavel Minaev