Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I declare an overloaded operator in an abstract class and override it in a derived non-abstract class?

I'm trying to write an abstract class with some pure virtual binary operators, which should be implemented by the derived class in order to accomplish operator polymorphism. Here's a simplified example:

class Base {
public:
    virtual const Base& operator+ (const Base&) const = 0;
};

class Derived : public Base {
public:
    const Derived& operator+ (const Derived&) const;
};

const Derived& Derived::operator+ (const Derived& rvalue) const {
    return Derived();
}

It doesn't matter right now what the operator does, the important part is what it returns: it returns a temporary Derived object, or a reference to it. Now, if I try to compile, I get this:

test.cpp: In member function ‘virtual const Derived& Derived::operator+(const Derived&) const’:
test.cpp:12:17: error: cannot allocate an object of abstract type ‘Derived’
test.cpp:6:7: note:   because the following virtual functions are pure within ‘Derived’:
test.cpp:3:22: note:    virtual const Base& Base::operator+(const Base&) const

What's wrong? Isn't operator+ (the only pure virtual function in Base) being overriden? Why should Derived be abstract as well?

like image 553
Michele De Pascalis Avatar asked Oct 21 '12 14:10

Michele De Pascalis


People also ask

How do you declare an overloaded operator?

Overloaded operators are implemented as functions and can be member functions or global functions. An overloaded operator is called an operator function. You declare an operator function with the keyword operator preceding the operator.

Is method overloading possible in abstract class?

Yes,Method overloading is possible in an Abstract class in Java.

How do you overload a class operator in C++?

This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.

Can you overload operators in C#?

A user-defined type can overload a predefined C# operator. That is, a type can provide the custom implementation of an operation in case one or both of the operands are of that type. The Overloadable operators section shows which C# operators can be overloaded. Use the operator keyword to declare an operator.


2 Answers

Although the return type in Derived can be co-variant to the base one, you can't do the same with the argument types. I.e., the overriding function should look like this:

class Derived : public Base 
{ 
public: 
    const Derived& operator+ (const Base&) const; 
}; 
like image 87
Igor R. Avatar answered Sep 17 '22 00:09

Igor R.


This kind of overloading is not possible with a normal abstract class in a clean way. First: you should declare + as non member Overload operators as member function or non-member (friend) function?.

The best you can get is to inherit from a templated interface if you really need this functionality:

template<typename T>
class AddEnabled {
  public:
    friend T operator+ (T const& left, T const& right) {
      return left+=right;
    }
};

Now you write

class Foo: public AddEnabled<Foo>{
  Foo():mVal(0){
  }

  Foo& operator+=(Foo const& foo){
    mVal+=foo.mVal;
  }

 private:
  int mVal;
}

If you comment out Foo& operator+=(Foo const& foo){ you will get a compiler error saying that the operator is not implemented. If you want to know more about the principles involved lookup http://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick and http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

HTH, Martin

like image 24
Martin Avatar answered Sep 20 '22 00:09

Martin