C++继承比较运算符和输出运算符的重载

C++ inheritance of overloading of comparison and output operators

我有一些带有几何图形的 C++ classes,我需要重载比较运算符(例如 ><= 等。 ) 和输出运算符 << 每次我需要打印或比较这些 classes 的任何实例时,我指的是它们区域的值(我使用 getArea()).

我试图将这些运算符重载放在父级 class GeometricShape 但我遇到了各种编译器错误,这对我来说没有多大意义。

如果我在每个子节点中放置运算符重载 class 它工作正常,但它非常丑陋且不理想(很多代码重复)。

如何删除此代码重复并将重载的运算符移至父级 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();
    }
};

这段代码有很多问题需要修复。

外部独立 operator< 应该没有编译错误:

bool operator<(GeometricShape& s1, GeometricShape& s2) {
    return s1.getArea() < s2.getArea();
}
  1. 您应该将 operator< 的两个参数都标记为 const。这也需要将 getArea 的所有实例标记为常量。
  2. getArea 应在 GeometricShape 中标记为虚拟。所有的 sub类 也应该用 override 标记方法。否则,将调用 GeometricShape 的 getArea。
  3. 在几何形状中,您应该使 getArea() 函数纯虚拟。
  4. 要确保派生的对象 类 调用了正确的析构函数,您应该将 GeometricShape 中的析构函数标记为虚拟。

这将使您的方法签名类似于:

对于几何形状:

virtual double getArea() const = 0;

对于派生类:

double getArea() const override;

编辑:评论中有很多关于如何改进这段代码的建议。我已经尽力把它们总结在这里了。