Страницы

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

понедельник, 8 апреля 2019 г.

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

Пишу класс рациональных чисел. Хочу перегрузить оператор сложения, чтобы можно было складывать с дробями целые числа. Всё получилось, но проблема в том что возможна запись <мой класс> = <мой класс> + <целое число> Если же я пишу так: <мой класс> = <целое число> + <мой класс> всё крашится: 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; }


Ответ

Вот в том числе и по этой причине такие операторы рекомендуется реализовывать не методами класса, как у вас, а отдельными (дружественными) функциями. Вы реализовали именно оператор сложения, в котором целое является правым операндом. Реализовать оператор сложения для целого числа в качестве левого операнда методом класса невозможно в принципе. Его в любом случае придется реализовывать обычной функцией.
Но тут на самом деле стоит сделать шаг назад и посмотреть на общий дизайн. Вам на самом деле вообще не нужно реализовывать операторы для сложения с целыми числами. Ваш класс 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;
и ничего для этого дополнительно писать не надо.
Если вам при этом захочется написать отдельные реализации для операций с обычными числами (например, в целях оптимизации) - вы можете это сделать. Но лучше это делать обычными функциями с двумя параметрами, как показано выше, а не методами класса.

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

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