5

Do polymorphism and operator overloading mix together? You can't do polymorphism without pointers, as it is explained in this answer and also you can't do operator overloading with pointers as explained here.
So there really is no way to do this, right?

Community
  • 1
  • 1
titus
  • 5,512
  • 7
  • 25
  • 39

3 Answers3

7

Yes there is. You didn't read the answers properly.

Here is a short demo:

#include <iostream>
using namespace std;

struct X
{
    int value;
    virtual void operator += (int x)
    {
        value += x;
    }
};

struct Y : X
{
    virtual void operator += (int x)
    {
        value *= x;
    }
};

void do_stuff(X& x)
{
    x += 10;
    cout << "Final value " << x.value << endl;
}

int main()
{
    X x;
    x.value = 10;
    Y y;
    y.value = 10;
    do_stuff(x);
    do_stuff(y);

    return 0;
}

I'm not implying that this is a good idea, or that it's practical. It's simply just possible.

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
4

In brief:

Operator overloading is a static polymorphism.

Static polymorphism can be implemented using function overloading, operator overloading and templates.

I think you are considering dynamic polymorphism (virtual stuff) only.
On other hand, typically we don't see virtual function for overloaded operator, but still it's possible theoritically.

A correction: Runtime (dynamic) polymorphism can be done using pointer and reference.

iammilind
  • 68,093
  • 33
  • 169
  • 336
3

First, polymorphism works with both references and pointers. And operator overloading works with references. So there's no problem at that level.

There is a potential problem with binary operators. Direct language support for polymorphism on an operator only works on the left hand operand. Where as for something like binary +, one logically would expect double dispatch. While this can be implemented, it is somewhat more complex, especially if the hierarchies are open.

For operators like binary +, which normally return a new object, there is also the question of the return type. Typically, this can't be a reference, since there is no object with an appropriate type to refer to. Patterns like the letter-envelop idiom have been developed to deal with this, but they aren't necessarily simple, and they often have very significant run-time overhead. Or the overloaded operator returns a special type, which only saves its arguments, and knows how to calculate the value with the correct type when requested.

James Kanze
  • 150,581
  • 18
  • 184
  • 329