Mastarius
Mastarius

Reputation: 315

Redefinition of virtual operator== in derived class

I'm about to redefine the operator== on a derived class. The base class has a re-definition of operator== itself, which is:

virtual bool operator==(const Dress &c) const {
    return brand==c.brand && size==c.size
}

In this case i suppose brand==c.brand it's the same as this.brand==c.brand. On my derived class i'm using the same function signature.

virtual bool operator==(const Dress &c) const

My questions is:

Is it correct to check if the type of arguments matches by using

typeid(this) == typeid(c)

since this redefined function will only be called on derived class' elements? What i'm not understanding is, how can i redefine the function to return false when called on objects like derived_class_object == base_class_object ?

Base class

class Dress {
private:
    string brand;
    int size;
public:
Dress(string b="unknown", int s=40): brand(b), size(s) {}
virtual bool operator==(const Dress &c) const {
        return brand==c.brand && size==c.size
    }

Derived class

class Tshirt: public Dress {
private:
bool is_shortsleeve;
public:
Tshirt(string b="unknown", int s=40, bool t=true):Capo(b,s),is_shortsleeve(t) {}
virtual bool operator==(const Dress &c) const {

...

}

I need to check, beside other controls obviously, that both the elements belong to the derived class. Is it acceptable to do it as i wrote before?

Upvotes: 1

Views: 693

Answers (3)

Johannes
Johannes

Reputation: 6717

Is this what you were looking for?

#include <iostream>
#include <string>

class base
{
protected:
    int a;
public:
    base(int a) : a(a) {}
    virtual bool operator == (base & other) const
    {
        return (typeid(*this) == typeid(other)) && this->a == other.a;
    }
};

class derived : public base
{
public:
    derived(int a) : base(a)
    {}
    virtual bool operator == (base & other) const
    {
        derived* otherDerived = dynamic_cast<derived*>(&other);
        bool canBeCastToDerived = (0 != otherDerived);
        bool isExactlyTheSameType = (typeid(*this) == typeid(other));
        bool hasOtherProperties = false;

        if (otherDerived)
        {
            hasOtherProperties = (this->a == otherDerived->a);
        }

        return  canBeCastToDerived && isExactlyTheSameType && hasOtherProperties;
    }
};

int main()
{
    using std::cout;
    base one(1);
    derived two(2);

    cout << (one == one) << "\n";
    cout << (one == two) << "\n";
    cout << (two == one) << "\n";
    cout << (two == two) << "\n";
}

EDIT 1: Included all the valid criticism in the comments.

EDIT 2: Changed example to explicitly include other variations.

Upvotes: 3

Gerhard Stein
Gerhard Stein

Reputation: 1563

First of all RunTimeTypeInformation (RTTI) should be enabled. Then you could use dynamic_cast<Derived*> and see if you get a valid pointer to the object. If the object was built with Derived it would return a valid pointer otherwise nullptr and you know it is something else. Of course you can retry that with dynamic_cast<Base*>.

typeid() will also work but with typeid(*this) == typeid(c)

Upvotes: 3

Luca Pizzamiglio
Luca Pizzamiglio

Reputation: 313

In general, the this and c has different type, so the check you need is

typeid(*this) == typeid(c)

Upvotes: 1

Related Questions