I have some C++ classes with geometric figures where I need to overload the comparison operators (such as >
, <
, =
, etc..) and the output operator <<
in a way that every time I need to print or compare any instance of these classes, I refer to the value of their area (which I get using getArea()
).
I tried to place those operator overloads in the parent class GeometricShape
but I got all kinds of compiler errors which made no much sense to me.
If I place the operator overloads in each child class it works fine, but it's quite ugly and not ideal (a lot of code repetition).
How can I remove this code repetition and move the operators overloading to the parent class?
using namespace std;
#include <iostream>
#include <stdlib.h>
#include <math.h>
class GeometricShape
{
public:
double getArea();
};
class Poligon : public GeometricShape
{
protected:
double base;
double height;
public:
Poligon(double base, double height) : base(base), height(height) {}
Poligon(float base, float height) : Poligon(double(base), double(height)) {}
Poligon(int base, int height) : Poligon(double(base), double(height)) {}
double getBase()
{
return this->base;
}
double getHeight()
{
return this->height;
}
void setBase(double b)
{
this->base = b;
}
void setHeight(double a)
{
this->height = a;
}
};
class Rectangle : public Poligon
{
public:
Rectangle(double base, double height) : Poligon(base, height) {}
Rectangle(float base, float height) : Poligon(base, height) {}
Rectangle(int base, int height) : Poligon(base, height) {}
double getArea()
{
return base * height;
}
// HOW TO MOVE THIS CODE INTO GeometricShape and reuse it???
friend ostream& operator<<(ostream& out, Rectangle &obj)
{
out << obj.getArea();
return out;
}
friend bool operator==(Rectangle &obj1, Rectangle &obj2)
{
return obj1.getArea() == obj2.getArea();
}
friend bool operator>(Rectangle &obj1, Rectangle &obj2)
{
return obj1.getArea() > obj2.getArea();
}
friend bool operator<(Rectangle &obj1, Rectangle &obj2)
{
return obj1.getArea() < obj2.getArea();
}
friend bool operator <= (Rectangle &obj1, Rectangle &obj2)
{
return obj1.getArea() <= obj2.getArea();
}
friend bool operator >= (Rectangle &obj1, Rectangle &obj2)
{
return obj1.getArea() >= obj2.getArea();
}
};
class Triangle : public Poligon
{
public:
Triangle(double base, double height) : Poligon(base, height) {}
Triangle(float base, float height) : Poligon(base, height) {}
Triangle(int base, int height) : Poligon(base, height) {}
double getArea()
{
return (base * height)/2;
}
// HOW TO MOVE THIS CODE INTO GeometricShape and reuse it???
friend ostream& operator<<(ostream& out, Triangle &obj)
{
out << obj.getArea();
return out;
}
friend bool operator==(Triangle &obj1, Triangle &obj2)
{
return obj1.getArea() == obj2.getArea();
}
friend bool operator>(Triangle &obj1, Triangle &obj2)
{
return obj1.getArea() > obj2.getArea();
}
friend bool operator<(Triangle &obj1, Triangle &obj2)
{
return obj1.getArea() < obj2.getArea();
}
friend bool operator <= (Triangle &obj1, Triangle &obj2)
{
return obj1.getArea() <= obj2.getArea();
}
friend bool operator >= (Triangle &obj1, Triangle &obj2)
{
return obj1.getArea() >= obj2.getArea();
}
};
class Circle : public GeometricShape
{
double radius;
public:
Circle(double radius) : radius(radius) {}
double getArea()
{
return (radius * radius) * M_PI;
}
double getRadius()
{
return this->radius;
}
void setRadius(double r)
{
this->radius = r;
}
// HOW TO MOVE THIS CODE INTO GeometricShape and reuse it???
friend ostream& operator<<(ostream& out, Circle &obj)
{
out << obj.getArea();
return out;
}
friend bool operator==(Circle &obj1, Circle &obj2)
{
return obj1.getArea() == obj2.getArea();
}
friend bool operator>(Circle &obj1, Circle &obj2)
{
return obj1.getArea() > obj2.getArea();
}
friend bool operator<(Circle &obj1, Circle &obj2)
{
return obj1.getArea() < obj2.getArea();
}
friend bool operator <= (Circle &obj1, Circle &obj2)
{
return obj1.getArea() <= obj2.getArea();
}
friend bool operator >= (Circle &obj1, Circle &obj2)
{
return obj1.getArea() >= obj2.getArea();
}
};
There are quite a few things that need to be fixed with this code.
An external freestanding operator<
should give no compilation errors:
bool operator<(GeometricShape& s1, GeometricShape& s2) {
return s1.getArea() < s2.getArea();
}
override
as well. Otherwise, getArea from GeometricShape will be called.getArea()
function pure virtual.This would make your method signature look something like:
For GeometricShape:
virtual double getArea() const = 0;
For derived classes:
double getArea() const override;
EDIT: There were quite a lot of suggestions in the comments on how to improve this piece of code. I have tried my best to summarise them here.