Как можно улучшить код класса сложения дробей?

Компьютеры программирование C++ cpp

/*
*
*
*
*/

#include <iostream>

using namespace std;

class drob {
private:
int mc;
int mz;

void sokr (){
int n;
mc>mz?n=mz:n=mc;
for (int i = 2; i < n+1; i++) {
for (int j = 1; i < n; j++)
if (mc%i == 0 && mz%i == 0) {
mc = mc/i;
mz = mz/i;
}
else break;
}
}
public:

drob (int a, int b) {
mc = a;
mz = b;
sokr();
}
int getchis(){
return mc;
}
int getznam(){
return mz;
}
void show(){
sokr();
cout << mc << "/" << mz;
}

// drob + drob, drob + int, int + drob
drob operator + (drob &tmp) {
return drob (mc*tmp.mz + tmp.mc*mz, mz*tmp.mz);
}
drob operator + (int val) {
return drob (mc+val*mz, mz);
}
friend drob operator + (int val, drob &tmp) { // *this не передается
return drob (tmp.mc+val*tmp.mz, tmp.mz);
}

// drob - drob, drob - int, int - drob
drob operator - (drob &tmp) {
return drob (mc*tmp.mz - tmp.mc*mz, mz*tmp.mz);
}
drob operator - (int val) {
return drob (mc-val*mz, mz);
}
friend drob operator - (int val, drob &tmp) { // *this не передается
return drob (val*tmp.mz-tmp.mc, tmp.mz);
}

// drob * drob, drob * int, int * drob
drob operator * (drob &tmp) {
return drob (mc*tmp.mc, mz*tmp.mz);
}
drob operator * (int val) {
return drob (mc*val, mz);
}
friend drob operator * (int val, drob &tmp) { // *this не передается
return drob (val*tmp.mc, tmp.mz);
}

// drob / drob, drob / int, int / drob
drob operator / (drob &tmp) {
return drob (mc*tmp.mz, mz*tmp.mc);
}
drob operator / (int val) {
return drob (mc, mz*val);
}
friend drob operator / (int val, drob &tmp) { // *this не передается
return drob (val*tmp.mz, tmp.mc);
}

// drob / drob, drob / int, int / drob
bool operator == (drob &tmp) {
bool b;
if (mc == tmp.mc && mz == tmp.mz) {
cout << " верно";
b = 1;
}
else {
cout << " неверно";
b = 0;
}
return b;
}
bool operator == (int val) {
bool b;
if (mc == val*mz) {
cout << " верно";
b = 1;
}
else {
cout << " неверно";
b = 0;
}
return b;
}
friend bool operator == (int val, drob &tmp) {
bool b;
if (tmp.mc == val*tmp.mz) {
cout << " верно";
b = 1;
}
else {
cout << " неверно";
b = 0;
}
return b;
}

};

int main() {

cout<<"\n\tДействия + - * / с дробями\n";

cout << endl << endl;

drob a (1, 7);
drob b (4, 12);


drob c = a + b;
a.show();
cout << " + ";
b.show();
cout << " = ";
c.show();

cout << endl << endl;

drob d = a - b;
a.show();
cout << " - ";
b.show();
cout << " = ";
d.show();

cout << endl << endl;

drob e = a * b;
a.show();
cout << " * ";
b.show();
cout << " = ";
e.show();

cout << endl << endl;

drob f = a / b;
a.show();
cout << " : ";
b.show();
cout << " = ";
f.show();

cout << endl << endl;

drob g (4, 10);
drob h (64, 1024);
g.show();
cout << " == ";
h.show();
g == h;

cout << endl<< endl;

int k = 3;

drob i = a + k; // drob + int
a.show();
cout << " + " << k << " = ";
i.show();

cout << endl << endl;

drob j = k + a; // int + drob

cout << k << " + ";
a.show();
cout << " = ";
j.show();

cout << endl << endl;

drob m = k / a;
cout << k << " / ";
a.show();
cout << " = ";
m.show();



}

Примечание:
http://pastebin.com/qWvUGgrx
Ответы:
если не требуется произвольно заданная точность операций, то достаточно лишь перевести дробь в десятичную, представить как double и выполнять произвольные операции.
не совсем понял, зачем понадобился класс.
1) Сокращение написать по-человечески.
2) Добавить поддержку отрицательных дробей.
1) Для повышения точности советую знаменатель делать unsigned
2) нет проверки на нулевой знаменатель. Я бы выбрасывал исключение
3) за дизайн ф-ций show() и operator==() я, на месте учителя, наказал бы достаточно сильно.
Побочные эффекты без надобности. УЖАС!!! Что будете делать, если понадобится выводить не на экран а в файл?
Ну, во первых, не следует делать членом класса метод show. Просто перегрузите оператор << для cout
Во вторых, методы, которые не изменяют члены класса сделайте const, а ссылочные параметры, которые не изменяются сделать const&. Отсутствуют операторы +=, -=, *=, /=. Нет оператора != и унарного минуса. Вместо пары арифметических операторов (для int и drob) достаточно конструктора от целочисленного значения и операторов умножения только c drob.
в третьих, отсутствует конструктор копирования.
Да и сокращение дроби выполняется поиском наибольшего общего кратного общеизвестным алгоритмом, а не перебором делителей. То есть надо находить остотк числителя, потом остаток от деления на остаток и т.д.
В четвертых, опять же не следует в методах == делать вывод на консоль
В пятых, нет операторов приведения к типам double, float,
В шестых, хорошо бы сделать и реализовать методы ToString и FromString (статический), которые умеют записывать в строку и считывать из строки.
Далее, нет контроля переполнения при умножении, проверки деления на ноль.
Хорошо бы добавить в класс несколько статических констант, например, drob::One, drob::Zero, drob::MinusOne, drob::Half
Да и вообще, правильно говорили - переименовать класс во Frac или Fraction.
Если обобщать, то можно было бы параметризовать класс базовым типом - у Вас он сейчас реализован на int.
Но никто ему не мешает реализоваться на long или short. Если программируете на Visual Studio, то рекомендую методы getznam, getchis преобразовать в свойства.


12 лет назад

RPI.su - самая большая русскоязычная база вопросов и ответов. Наш проект был реализован как продолжение популярного сервиса otvety.google.ru, который был закрыт и удален 30 апреля 2015 года. Мы решили воскресить полезный сервис Ответы Гугл, чтобы любой человек смог публично узнать ответ на свой вопрос у интернет сообщества.

Все вопросы, добавленные на сайт ответов Google, мы скопировали и сохранили здесь. Имена старых пользователей также отображены в том виде, в котором они существовали ранее. Только нужно заново пройти регистрацию, чтобы иметь возможность задавать вопросы, или отвечать другим.

Чтобы связаться с нами по любому вопросу О САЙТЕ (реклама, сотрудничество, отзыв о сервисе), пишите на почту [email protected]. Только все общие вопросы размещайте на сайте, на них ответ по почте не предоставляется.