C++ 重载 == 比较不同类的对象

Kel*_*eli 4 c++ overloading class

对于实验室,我必须重载 + 运算符来添加来自同一类的对象,并重载 == 运算符来比较来自两个不同类的对象。重载 == 运算符的函数给我带来了很多麻烦(可能是因为我使用它来比较不同类的对象区域)。我一直在不懈地寻找解决方案,并且尝试了所有发现的建议但没有成功,所以我不得不使用我的特定代码来询问:

// OBJECTIVES:
// Add areas of 2 circles
// Add areas of 2 rectangles
// Compare areas of a circle and a rectangle

#include <iostream>
using namespace std;

// **********************Header*********************
class circle
{
    friend bool operator==(const circle& ,
                           const circle&);
    friend circle operator+(const circle& , 
                            const circle&);
public:
    double radius, area;
    void calcArea();
};

class rect
{
    friend bool operator==(const rect& , 
                           const rect&);
    friend rect operator+(const rect& , 
                          const rect&);
public:
    double length, width, area;
    void calcArea();
};

void displayMenu();
// **************************************************

// **********************Program*********************
int main()
{
    int selection; // variable for menu selection

    circle firstCircle; // objects from circle class
    circle secondCircle;

    rect firstRect; // objects from rect class
    rect secondRect;

    do {
        displayMenu();
        cin >> selection;
        cout << endl;

        if (selection == 1) // add area of 2 circles
        {
            firstCircle.calcArea();
            secondCircle.calcArea();
            circle thirdCircle = firstCircle + secondCircle;

            cout << "The sum of your two circles is: " ;
            cout << thirdCircle.area;
            cout << endl;
        }

        else if (selection == 2) // add area of 2 rectangles
        {
            firstRect.calcArea();
            secondRect.calcArea();
            rect thirdRect = firstRect + secondRect;

            cout << "The sum of your two rectangles is: " ;
            cout << thirdRect.area;
            cout << endl;

        }

        else if (selection == 3) // compare areas of a circle and a rectangle
        {
            firstCircle.calcArea();
            firstRect.calcArea();

            if (firstCircle.area == firstRect.area)
            {
                cout << "The area of your circle is equal to that of your rectangle." << endl;
            }
            else
            {
                cout << "The area of your circle is not equal to that of your rectangle." << endl;
            }
        }

        else if (selection == 4) // exit program
        {
            return 0;
        }

        else
        {
            cout << "Please enter a valid selection.";
            cout << endl;
            continue;
        }
    } while (1);

    return 0;
}
// **************************************************

// ******************Implementation******************
void circle::calcArea() // compute circle area
{
    cout << "Enter a radius: ";
    cin >> radius;

    area = 3.14159265359 * radius * radius;
}

void rect::calcArea() // compute rectangle area
{
    cout << "Enter a length: ";
    cin >> length;
    cout << "Enter a width: ";
    cin >> width;

    area = length * width;
}

bool operator==(const circle& firstCircle, // compare areas of objects
                const rect& firstRect)  // from different classes
{
    return (firstCircle.area == firstRect.area && 
            firstCircle.area == firstRect.area);
}

circle operator+ (const circle& firstCircle, // overload + for circle class
                    const circle& secondCircle)
{
    circle circleSum;

    circleSum.radius = firstCircle.radius + secondCircle.radius;
    circleSum.area = firstCircle.area + secondCircle.area;

    return circleSum;
}

rect operator+ (const rect& firstRect, // overload + for rect class
                    const rect& secondRect)
{
    rect rectSum;

    rectSum.length = firstRect.length + secondRect.length;
    rectSum.width = firstRect.width + secondRect.width;
    rectSum.area = firstRect.area + secondRect.area;

    return rectSum;
}

void displayMenu() // menu options
{
    cout << endl;
    cout << "What would you like to do?" << endl;
    cout << "1. Add the area of 2 circles."<< endl;
    cout << "2. Add the area of 2 rectangles."<< endl;
    cout << "3. Compare the area of a circle and a rectangle."<< endl;
    cout << "4. Exit.";
}
// **************************************************
Run Code Online (Sandbox Code Playgroud)

现在,我没有使用重载的 == 来比较矩形和圆形区域,因为这样我会遇到很多编译器错误。你们可以为我提供任何改变的帮助,我firstCircle.area == firstRect.areafirstCircle == firstRect不胜感激。

Ser*_*gey 5

有多种方法可以编写您想要的比较运算符。最简单的方法,无需干预类代码,只需实现几个非成员运算符:

bool operator==(const circle& c, const rect& r) { return r.area == c.area; }
bool operator==(const rect& r, const circle& c) { return c.area == r.area; }
Run Code Online (Sandbox Code Playgroud)

您可以将它们放在函数上方的源文件中main,或者放在单独的头文件中。请注意,他们不需要是circle和的朋友rect,因为area成员是公开的。

另一种方法是编写成员函数,但首先我们需要修复现有的比较运算符:

class circle
{
public:
    bool operator==(const circle& other) const { return area == other.area; }

    // ...skipped...
};
Run Code Online (Sandbox Code Playgroud)

它与您的版本有何不同以及为何不同?

  1. this它是一个与进行比较的成员函数other,仅采用一个参数。
  2. circle课堂外可以公开调用
  3. 它是 const 限定的,因为它只需要查找类数据而不进行修改。

const 限定符还允许您像这样比较 const 对象:

const circle c1 = getSomeCircle();
const circle& c2 = otherCircle;
c1 == c2; // Note: statement has no effect, despite it's syntax is correct.
c2 == c1;
Run Code Online (Sandbox Code Playgroud)

非 const 限定的比较将无法编译。总而言之,这是在 C++ 中编写比较运算符的最惯用的方式。

最后,让我们添加圆来进行矩形比较:

class rect;

class circle
{
public:
    bool operator==(const circle& other) const { return area == other.area; }
    bool operator==(const rect&) const;

    // ...skipped...
};

class circle { /* class definition skipped */ };

bool operator==(const rect& r) const { return area == r.area; }
Run Code Online (Sandbox Code Playgroud)

首先我们在这里声明了这个rect类。当类被声明但未定义时(即前向声明),我们可以使用指针引用它的实例,但不能使用实例本身。我们不能使用实例的原因之一是类的大小在定义之前是未知的。

然后我们声明成员operator==接受对前向声明类的引用,最后在rect定义之后我们可以实现运算符。

rect可以以circle相同的方式进行比较。