Изменяю код, в расчёте, может быть кому-нибудь пригодится. Задача: Даны две дроби a/b и c/d.
Создайте класс Fraction, который будет хранить дробь вида x/y. На вход: 2/3 4/5 Ответ: 22/15
PS Задачи сократить дробь нет. Надо только ввести две обыкновенные дроби с клавиатуры, сложить их и вывести ответ в виде также обыкновенной дроби. Цель продемонстрировать перегрузку операторов.
#include <iostream>
#include <cstring>
using namespace std;
typedef long long int ll_int;
class Fraction{
ll_int x, y;
public:
Fraction(ll_int x = 0, ll_int y =1): x(x),y(y){}
void read(); // Ввод обыкновенных дробей с клавиатуры
void show(); // Вывод результата суммы дробей.
Fraction operator +(Fraction &); //Перегрузка оператора +
};
void Fraction::read(){
char s;
cin >> x >> s >> y; //х - числитель, s - "/", у - знаменатель
}
void Fraction::show(){
cout << x << "/" << y; //х - числитель, "/", у - знаменатель
}
Fraction Fraction::operator +(Fraction &v){
x = x * v.y + v.x * y; //Сложение числителей первого и второго числа
y = y * v.y;
return *this;
}
int main(){
Fraction a, b, c;
a.read();
b.read();
c = a + b;
c.show();
return 0;
}
У вас уже есть замечания в комментариях. Вот мои:
read и show полностью специализированы на консоль. В
общем случаи, правильнее, если они будут получать в аргумент
обьект потока. read(std::istream&) и show(std::ostream&). Также, можно
вместо этого определять операторы >> и <<. operator *=, а operator * можете определить (с его помощью) вне
класса.Вы хотите(в программе) дробь умножить(сложить) на дробь, а не на число. Поэтому:
typedef long long int ll_int;
class Fraction{
ll_int x, y;
public:
Fraction(ll_int x = 0, ll_int y =1): x(x),y(y){}
void read(); // Ввод обыкновенных дробей с клавиатуры
Fraction& operator *=(const Fraction&);
Fraction& operator +=(const Fraction&);
void show() const;
};
void Fraction::read()
{
using std::cin;
cin >> x; //пытаемся вводить числитель
if (cin) { //если ввод был нормальным, продолжаем
if (cin.peek() == '/') { //если следующий символ...
cin.ignore(); // пропускаем
cin >> y;
}
else // если нет символа '/'
y = 1;
}
}
// *= и += стоит реализовать для удобства использования класса
Fraction& Fraction::operator *=(const Fraction& f)
{
x *= f.x;
y *= f.y;
return *this;
}
Fraction& Fraction::operator +=(const Fraction& f)
{
x = x * f.y + y * f.x;
y *= f.y;
return *this;
}
void Fraction::show() const
{
cout << x << "/" << y;
}
// и вне класса уже можем определять + и *
Fraction operator *(Fraction& f1, const Fraction& f2)
{ return f1 *= f2; }
Fraction operator +(Fraction& f1, const Fraction& f2)
{ return f1 += f2; }
main()
{
Fraction a, b, c;
a.read();
b.read();
c = a + b;
c.show();
cout << endl;
// Так как оператор *= возвращает ссыльку на этот обьект
// можем сразу выполнить и умножение и вывод
(a *= b).show();
return 0;
}
Обновление:
Fraction Fraction::operator +(ll_int v){...} Это определение оператора, суммирующая дробь с числом(обьектом v типа long long) . Обьект v не содержится в вашем классе, поэтому x = x * y.v + x.v * y; это ошибка. Если хотите, чтобы операнд был не дробью, а так, как вы пытаетесь, то нужно сделать то же самое, как я вам показал, с разницей, что знаменатель равен 1:
Fraction Fraction::operator +(ll_int v)
{
Fraction f; // значения по умолчанию f.x == 0 и f.y == 1
f.x = x + v * y;
f.y = y;
//так как нет дроби (`v` - это целое число)
return f;
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей