Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Перегрузка оператора сложения для дробей

#cpp #перегрузка_операторов #операторы


Пишу класс рациональных чисел. Хочу перегрузить оператор сложения, чтобы можно было
складывать с дробями целые числа. Всё получилось, но проблема в том что возможна запись 
<мой класс> = <мой класс> + <целое число> 
Если же я пишу так:
<мой класс> = <целое число> + <мой класс>
всё крашится: no match for 'operator+' (operand types are 'int' and 'Number')

Вoт код в .h:

class Number {
public:
    Number(int numerator = 0, int denominator = 1);

    int getNumerator() {return this->numerator;}
    int getDenominator() {return this->denominator;}
    string toString();

    // определяем арифметические действия дробей с дробями
    Number operator+ (Number &other);
    Number operator- (Number &other);
    Number operator* (Number &other);
    Number operator/ (Number &other);

    // определяем арифметические действия дробей с целыми числами
    Number operator+ (int i);
protected:
    int numerator; // числитель
    int denominator; // знаменатель
};


Код в .cpp:

Number Number::operator+(int i) {
    Number res(i * this->denominator() + this->numerator(), this->denominator());
    return res;
}

    


Ответы

Ответ 1



Вот в том числе и по этой причине такие операторы рекомендуется реализовывать не методами класса, как у вас, а отдельными (дружественными) функциями. Вы реализовали именно оператор сложения, в котором целое является правым операндом. Реализовать оператор сложения для целого числа в качестве левого операнда методом класса невозможно в принципе. Его в любом случае придется реализовывать обычной функцией. Но тут на самом деле стоит сделать шаг назад и посмотреть на общий дизайн. Вам на самом деле вообще не нужно реализовывать операторы для сложения с целыми числами. Ваш класс Number уже обладает конвертирующим конструктором, который умеет преобразовывать целые числа в ваш Number. После этого ваши готовые операторы для операндов типа Number уже сами сделают все правильно. Для этого, однако необходимо 1) реализовать их обычными функциями, 2) не забыть о const в параметрах-ссылках, который у вас почему-то отсутствует. class Number { public: Number(int numerator = 0, int denominator = 1); // определяем арифметические действия дробей с дробями friend Number operator +(const Number &lhs, const Number &rhs); friend Number operator -(const Number &lhs, const Number &rhs); friend Number operator *(const Number &lhs, const Number &rhs); friend Number operator /(const Number &lhs, const Number &rhs); protected: // <- ??? int numerator; // числитель int denominator; // знаменатель }; Такой класс уже сам по себе будет поддерживать Number a(2, 3); Number b = a + 1; Number c = 25 + a; и ничего для этого дополнительно писать не надо. Если вам при этом захочется написать отдельные реализации для операций с обычными числами (например, в целях оптимизации) - вы можете это сделать. Но лучше это делать обычными функциями с двумя параметрами, как показано выше, а не методами класса.

Ответ 2



#include using namespace std; struct Number { int numerator; // числитель int denominator; // знаменатель Number(int num = 0, int denom = 1) : numerator(num), denominator(denom) {} //... // определяем арифметические действия дробей с целыми числами Number operator+ (int i) { return Number(i * denominator + numerator, denominator); } friend Number operator +(const int i, const Number& N) { return Number(i * N.denominator + N.numerator, N.denominator); } friend ostream& operator <<(ostream& os, const Number& N) { os << N.numerator << " / " << N.denominator; return os; } }; int main() { Number test(4, 2); std::cout << 5 + test; return 0; // теперь все нормально! } просто оператор определите и еще можете при возвращении Number производить еще и сокращение дроби... и не нужно делать данные закрытыми, если вы всеравно обеспечиваете доступ ко всем данным! Если вам удобно, то вы можете не определить int + Number, но в кодах написать не 5 + Number, а Number(5) + Number...

Комментариев нет:

Отправить комментарий