3
votes

How do I get an overloaded relational operator in a class to be called from a function in the parent class that is handed a const reference to a base class as a parameter? The following code demonstrates what I would like to do:

class Object 
{
public:
    virtual ~Object(void);
    virtual int compare(Object const& obj) const;
};

int Object::compare(Object const & obj) const {
    if(this == &obj)
    {
        return 0;
    }
    else if(this < &obj)
    {
        return -1;
    } else{
        return 1;
    }
}

class Integer: public Object
{
private:
    int myInt;
public:
    Integer(int i);
    bool operator==(const Integer& integer);
};

bool Integer::operator==(Integer const &integer) {
    if(myInt == integer.myInt)
    {
        return true;
    }
    return false;
}

How do I get the compare function in the base class to call the == operator in the child class, keeping in mind I have other child classes as well?

I have tried dynamic_cast<> but for some reason it wont work.

2
Note you just compare addresses not objects in base class. - xinaiz

2 Answers

0
votes

You can add another virtual method isEqual to connect with the Integer::operator==.

The only requirement is to keep the Object::isEqual signature in the class Integer. You should also keep in mind that your Object::compare method can be (accidentally) called on objects of different types.

class Object 
{
protected:
    virtual bool isEqual(Object const& obj) const
      { return this == &obj; }
public:
    virtual ~Object(void);
    virtual int compare(Object const& obj) const;
};

int Object::compare(Object const & obj) const {
    if(isEqual(obj))
    {
        return 0;
    }
    else if(this < &obj)
    {
        return -1;
    } else{
        return 1;
    }
}

class Integer: public Object
{
private:
    int myInt;
protected:
    virtual bool isEqual(Object const& obj) const
      { if (!dynamic_cast<const Integer*>(&obj))
          return false;
        return *this == (const Integer&) obj;
      }
public:
    Integer(int i);
    bool operator==(const Integer& integer);
};
0
votes

I would do:

#include <iostream>

class Object 
{
public:
    virtual ~Object(void) {};
    int compare(Object const& obj) const;
    virtual bool operator==(Object const& integer) const = 0;
    virtual bool operator<(Object const& integer) const = 0;
    virtual bool operator>(Object const& integer) const = 0;
};

int Object::compare(Object const& obj) const
{
    if(*this == obj)
        return 0;
    else if(*this < obj)
        return -1;
    else return 1;
}

class Integer: public Object
{
private:
    int myInt;
public:
    Integer(int i) : myInt(i) { };
    virtual bool operator==(Object const& integer) const override;
    virtual bool operator<(Object const& integer) const override;
    virtual bool operator>(Object const& integer) const override;
};

bool Integer::operator==(Object const& integer) const
{
    return myInt == dynamic_cast<Integer const&>(integer).myInt;
}

bool Integer::operator<(Object const& integer) const
{
    return myInt < dynamic_cast<Integer const&>(integer).myInt;
}

bool Integer::operator>(Object const& integer) const
{
    return myInt > dynamic_cast<Integer const&>(integer).myInt;
}
int main()
{
    Integer a(2), b(2), c(3);
    std::cout << a.compare(b) << std::endl;
    std::cout << b.compare(c) << std::endl;
    std::cout << c.compare(a) << std::endl;
}

But in reality you should just provide virtual compare function in inherited class like so:

class Object 
{
public:
    virtual ~Object(void) {};
    virtual int compare(Object const& obj) const = 0;
};

class Integer: public Object
{
private:
    int myInt;
public:
    Integer(int i) : myInt(i) { };
    virtual int compare(Object const& object) const override;
    bool operator==(Integer const& integer) const;
    bool operator<(Integer const& integer) const;
    bool operator>(Integer const& integer) const;
};

int Integer::compare(Object const& object) const
{
    Integer const& ref = dynamic_cast<Integer const&>(object);
    if(ref == *this)
        return 0;
    else if(ref > *this)
        return 1;
    else return -1;
}

bool Integer::operator==(Integer const& integer) const
{
    return myInt == integer.myInt;
}

bool Integer::operator<(Integer const& integer) const
{
    return myInt > integer.myInt;
}

bool Integer::operator>(Integer const& integer) const
{
    return myInt < integer.myInt;
}