C ++ Перегрузка == для сравнения объектов из разных классов - PullRequest
0 голосов
/ 30 октября 2018

В лаборатории мне пришлось перегрузить оператор +, чтобы добавить объекты из одного класса, и оператор ==, чтобы сравнить объекты из двух разных классов. Функция перегрузки оператора == доставляет мне много хлопот (вероятно, потому, что я использую ее для сравнения областей объектов разных классов). Я неустанно искал решение, и все предложения, найденные безуспешно, перепробовал, поэтому я вынужден спросить, используя мой конкретный код:

// 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.";
}
// **************************************************

Прямо сейчас я не использую перегруженный == для сравнения областей прямоугольника и круга, потому что тогда я получаю много ошибок компилятора. Любая помощь, которую вы, ребята, можете предложить мне, чтобы я смогла изменить firstCircle.area == firstRect.area на firstCircle == firstRect, была бы очень признательна.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Существует несколько подходов для написания оператора сравнения, который вы хотите. Самый простой способ, без вмешательства вашего кода класса, это просто реализовать пару операторов, не являющихся членами:

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; }

Вы можете поместить их в исходный файл над функцией main или в отдельный заголовочный файл. Обратите внимание, что они не должны быть друзьями circle и rect, так как area участник является публичным.

Другой способ - написать функции-члены, но сначала нам нужно исправить существующие операторы сравнения:

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

    // ...skipped...
};

Чем и чем она отличается от вашей версии?

  1. Это функция-член, которая сравнивает this с other, принимая только один аргумент.
  2. Общедоступно звонить извне circle класса
  3. Это константная квалификация, потому что для этого требуется только поиск данных класса без изменений.

Также квалификатор 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;

Неконстантное сравнение не скомпилируется. В общем, это самый идиоматический способ написания операторов сравнения на 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; }

Здесь сначала мы объявили класс rect. Когда класс объявлен, но не определен (то есть предварительное объявление ), мы можем использовать указатели и ссылки на его экземпляры, но не сами экземпляры. Одна из причин, по которой мы не можем использовать экземпляры, заключается в том, что размер класса неизвестен до его определения.

Затем мы объявляем член operator==, принимающий ссылку на объявленный вперед класс, и, наконец, после определения rect мы можем реализовать оператор.

rect - circle сравнение может быть реализовано одинаково.

0 голосов
/ 30 октября 2018

Перегрузка оператора может быть перегружена, как показано ниже.

#include <iostream>
using namespace std;

class rect;

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

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

int main(int argc, char *argv[]) {
    circle c;
    rect r;
    if (c == r) {
        cout << "It was a miracle a random circle is equal to a random rectangle in size!!!" << endl;
    }
    return 0;
}

bool operator == (const circle &c1, const circle &c2) {
    return c1.getArea() == c2.getArea();
}

bool operator == (const rect &r1, const rect &r2) {
    return r1.getArea() == r2.getArea();
}

bool operator == (const circle &c, const rect &r) {
    return c.getArea() == r.getArea();
}

bool operator == (const rect &r, const circle &c) {
    return c.getArea() == r.getArea();
}
...