Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
тех прог.doc
Скачиваний:
38
Добавлен:
14.11.2019
Размер:
3.59 Mб
Скачать

Программа 53. Обыкновенные дроби

Рассмотрим класс Fraction для моделирования обыкновенных дробей:

// Файл Fraction.h

#ifndef FractionH

#define FractionH

#include <iostream.h>

class Fraction{

int num; // Числитель

int denom; // Знаменатель

public:

Fraction(int n = 1, int m = 1){num = n; denom = m;} // Конструктор

// Методы доступа к закрытым членам

int numerator() {return num;}

int denominator() {return denom;}

Fraction operator+(Fraction a); // Метод сложения дробей

Fraction operator-() // Изменение знака дроби

{return Fraction(-num, denom);}

// Функция-друг вычитания дробей

friend Fraction operator-(Fraction a, Fraction b);

void print() // Метод для вывода дроби

{cout << num << ’/’ << denom;}

};

// Независимая функция для умножения дробей

Fraction operator*(Fraction a, Fraction b);

#endif

Оператор унарный минус не имеет аргументов потому, что ему как методу класса доступна дробь, для которой он вызывается. Вызов конструктора создает безымянный объект, значение которого возвращается из функции. Унарный минус реализован непосредственно в объявлении класса, то есть является встроенной функцией.

Метод класса сложения дробей имеет один аргумент, который является вторым слагаемым. Первым слагаемым является тот объект, для которого будет вызван этот метод.

// Файл Fraction.cpp

#include ”Fraction.h”

Fraction Fraction::operator+(Fraction b) // Сложение дробей

{

int cd = denom * b.denom; // Общий знаменатель

int ns = num * b.denom + b.num * denom; // Числитель суммы

Fraction sum(ns, cd); // sum – сумма дробей

return sum;

}

В функции сложения создается локальная переменная sum, числитель и знаменатель которой находятся по правилам сложения обыкновенных дробей. Ее значение возвращается как результат работы функции.

Функция-оператор вычитания дробей не является членом класса, поэтому она должна иметь два аргумента: уменьшаемое и вычитаемое. Эта функция является другом, поэтому ей разрешен доступ к закрытым членам класса.

Fraction operator-(Fraction a, Fraction b) // Вычитание дробей

{

int cd = a.denom * b.denom; // Общий знаменатель

int ns = a.num * b.denom - b.num * a.denom; // Числитель разности

Fraction subtr(ns, cd); // subtr – разность дробей

return subtr;

}

Функция-оператор умножения дробей, не являясь членом класса, должна иметь два аргумента – сомножителя. Для доступа к закрытым членам класса она использует открытые методы класса.

Fraction operator*(Fraction a, Fraction b)

{

int np = a.numerator() * b.numerator(); // Числитель произведения

int dp = a.denominator() * b.denominator(); // и знаменатель

return Fraction(np, dp);

}

В данной функции не создается именованная локальная переменная для произведения. Вместо этого вызывается конструктор, которому передаются числитель и знаменатель произведения, конструктор создает безымянный объект, значение которого и возвращается из функции, после чего этот безымянный объект уничтожается.

Испытаем класс Fraction.

// Файл FractOpr.cpp

#include <conio.h>

#include ”Fraction.h”

int main()

{

Fraction f12(1, 2), f13(1, 3), fs, fd, fp, fm;

cout << ”f12 = ”; f12.print(); cout << endl;

cout << ”f13 = ”; f13.print(); cout << endl;

fs = f12.operator+(f13); // Явный вызов функции-оператора

cout << ”fs = ”; fs.print(); cout << endl;

fd = f12 – f13; // Неявный вызов функции-оператора

cout << ”fd = ”; fd.print(); cout << endl;

fp = operator*(f12, f13) // Вычисление произведения

cout << ”fp = ”; fp.print(); cout << endl;

fm = -f12;

cout << ”fm = ”; fm.print(); cout << endl;

getch();

}

Программа выводит:

f12 = 1/2

f13 = 1/3

f1s = 5/6

fd = 1/6

fp = 1/6

fm = -1/2

В функции main для сложения и умножения дробей использованы явные вызовы соответствующих функций-операторов. Их неявный вызов выглядит более понятно:

fs = f12 + f13;

fp = f12 * f13;