简体   繁体   中英

Incremental operator overload in an abstract class C++

#include <iostream>
using namespace std;

class A{
private:
  double price;
public:
  A(double p):price(p){
  }
  virtual double abstractExample() = 0;
  A* operator++(int dummy){
    this->price = this->price + 1;
    return this;
  }
  virtual ~A(){
  }
  void print(){
    cout << price << endl;
  }
};

class B : public A {
  public:
    B(int p): A(p){
    }
    double abstractExample(){
        return 1;
    }
};

int main(){
  B* b = new B(5);
  b->print();
  b++->print();

  return 0;
}

So I have this abstract class A. I would like to overload the ++ operator. Normally I would just write A& operator ++(int dummy) but I in this case it has to return a pointer to an object because it's an abstract class. Is there any way I can do this without writing separate code in each inherited class?

This gives an input of 5, 5 instead of 5, 6.

arithmetic operators don't play well with polymorphic classes, unless you wrap the polymorphic implementation in a non-polymorphic wrapper.

Comments in the code explain the additions to your base class:

#include <iostream>
#include <memory>

using namespace std;

class A{
private:
  double price;
public:
  A(double p):price(p){
  }
  virtual double abstractExample() = 0;

  void increment()
  {
    this->price = this->price + 1;
  }

  // see below. clone in base must be abstract if the base class
  // is abstract. (abstractExample is pure so that's that)
  virtual std::unique_ptr<A> clone() const =0;

  virtual ~A(){
  }

  void print(){
    cout << price << endl;
  }
};

class B : public A {
  public:
    B(int p): A(p){
    }
    double abstractExample(){
        return 1;
    }

  std::unique_ptr<A> clone() const override
  {
    return std::make_unique<B>(*this);
  }

};

struct AB 
{
  AB(std::unique_ptr<A> p) : _ptr(std::move(p)) {}

  // pre-increment is easy
  AB& operator++() {
    _ptr->increment();
  }

  // post-increment is trickier. it implies clonability.
  AB operator++(int) {
    AB tmp(_ptr->clone());
    _ptr->increment();
    return tmp;
  }

  void print() {
    _ptr->print();
  }

  std::unique_ptr<A> _ptr;
};

int main(){
  AB b(std::make_unique<B>(5));
  b.print();

  // pre-increment
  (++b).print();

  // post-incrememnt will involve a clone.
  (b++).print();

  return 0;
}

but I in this case it has to return a pointer to an object because it's an abstract class.

No it doesn't. A reference is better actually. You won't run into slicing unless you return by value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM