0

I have searched far and wide for a specific answer to this question, and cannot find it. I am trying to create a base class with a virtual operator> that I can override in the derived class. Currently I'm having problems because declaring the function only requires one input variable (as in "bool operator> (Derived & a)" but attempting to define it in a cpp file tells me that it requires two inputs (as in "bool operator> (Derived & a, Derived & b))

I've tried defining the operator inline, but then I get errors where it thinks the derived class is still abstract because I'm passing in the derived type to the operator as shown above, instead of the base class. But if I pass the base class, then I cannot access the derived member variables I need to make the comparison.

I think I'm missing something simple here but I cannot seem to figure out what it is.

Hopefully you can help. Thanks

  • Did you define it as `bool Derived::operator>(Derived &a) ...`? – Nate Kohl Jan 11 '13 at 23:03
  • 1
    A virtual comparison operator is a bit hard to reason about. How do you want to compare two objects that have different types? – Kerrek SB Jan 11 '13 at 23:09
  • I want to compare objects that have the same types, but I won't know which type that is going in. I'd like to allow each type to specify its own comparison operator so that whichever are compared, a correct comparison can occur. – user1971357 Jan 12 '13 at 03:04

4 Answers4

1

For virtual calls to work from a reference/pointer of the base, you will need to use the base-type in the function, so for example

class Derived : public Base
{
    .... 
    bool operator>(Base &a)
    {
         Derived *pa = dynamic_cast<Derived *>(&a);
         return this->something > pa->something;   // Or whatever... 
    }

   .... 
};

If you change the type, it becomes a different function, and when you use the base pointer or reference to refer to operator>, it will use the one in the base-class.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

Old question, but I've hardly seen a useful/correct answer here, so I add my thoughts and suggestions.

First of all, comparison of polymorphic objects usually doesn't make that much sense. How would you compare an Elephant and a Colibri from a base class pointer Animal? And if you find a common criteria for the ordering, such as the animals' weight, you can also include it directly in the base class and define the comparison there.

So, the use cases for a virtual comparison are limited.

One valid use case is CRTP. Consider a static inheritance hierarchy, where a lot of derived classes share a common comparison mechanism, and only a few derived classes make it different. Then you can save the boilerplate in the derived classes with the following code:

struct base
{
    virtual ~base() = default;
    virtual bool operator> (base const& obj) const = 0;
};

struct derived: public base
{
    derived(int member) : member(member) {}
    int member = 0;

    virtual bool operator> (base const& obj) const
    {
        return member > static_cast<derived const&>(obj).member;
    }
};

int main()
{    
    //in reality one would use a unique_ptr, of course
    base* a = new derived(1);
    base* b = new derived(0);

    if(*a > *b)
    {
        //do something
    }

     return 0;
}

Caution: this works safely only if you're sure that the base const& parameter is really a derived const& (as e.g. in CRTP).

If not, you should use a dynamic_cast and add some error handling.

davidhigh
  • 14,652
  • 2
  • 44
  • 75
0

Why don't you leave operator>() non-virtual, und have it call a private virtual function?

Like so:

class Base {
public:
    bool operator>(Base &a) {
        return implementingFunction(a);
    }

private:
    virtual bool implementingFunction(Base &a) = 0;
};
lethal-guitar
  • 4,438
  • 1
  • 20
  • 40
  • 1
    And that solves exactly which problem? You will still have to have the same signature and do some sort of conversion between base and derived class inside the implementation. If we do a generic "compare(a, b)" type funciton that returns -1, 0, +1 (or some such) for the the "less than, equal and more than", then that does make sense. But if we simply want the "less than" function, then I don't really see the point [but maybe I'm missing something here]. – Mats Petersson Jan 11 '13 at 23:16
0
#include <iostream>
using namespace std;
class base{
public :
        virtual bool operator> (base& obj) { cout<<"b\n";return true;}
        virtual ~base(){}
};

class derived: public base{
public:
        virtual bool operator> (derived& obj) { cout<<"d\n";return true;}
        ~derived(){}
};

int main()
{

base *a=new derived(),b;
if(*a>b) { delete a; cout<<"Done!\n"; }

return 0;
}
  • I'm running into a problem where the fact that the base operator takes a base object while the derived operator takes a derived object, I get compiler errors when I try to call the function (passing in a pointer to base) which seems to be cause by inheritance not actually occurring. Your code suggests that having the input arguments different won't be a problem, so do you have any clue why this might be happening? – user1971357 Jan 12 '13 at 02:59