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