Реализация абстрактных типов данных с помощью классов С++, страница 2

2.  Текст программы.

Класс реализован в двух файлах: TFrac.h – описание класса, методов и полей; TFrac.cpp – реализация методов.

Листинг 1. TFrac.h

////////////////////////////////////////////////

//

//  Описание:Класс простой дроби

//

////////////////////////////////////////////////

#ifndef TFRAC_H

#define TFRAC_H

#include <iostream>

class QString;

using namespace std;

class TFrac

{

public:

    TFrac(            );

    TFrac(int a, int b);

    TFrac(QString drob);

        //Перегрузка оператора вывода в консоль

    friend ostream& operator<< (ostream&, const TFrac&          );

    TFrac& operator =          (const TFrac &f1                 );

    friend TFrac operator +    (const TFrac &f1, const TFrac &f2);

    friend TFrac operator *    (const TFrac &f1, const TFrac &f2);

    friend TFrac operator -    (const TFrac &f1, const TFrac &f2);

    friend TFrac operator /    (const TFrac &f1, const TFrac &f2);

    TFrac Square               (                                );

    TFrac Inverse              (                                );

    TFrac Minus                (                                );

    friend bool operator ==    (const TFrac &f1, const TFrac &f2);

    friend bool operator >     (const TFrac &f1, const TFrac &f2);

    int GetChislitel           (                                );

    int GetZnamenatel          (                                );

    QString GetStringChislitel (                                );

    QString GetStringZnamenatel(                                );

    QString ToString           (                                );

private:

    int chislitel;

    int znamenatel;

        //Показатель отрицательности

    bool znak;

};

#endif // TFRAC_H

Листинг 2. TFrac.cpp

////////////////////////////////////////////////

//

//  Описание:Класс простой дроби, реализация

//

////////////////////////////////////////////////

#include <QtCore>

#include "TFrac.h"

    //Перегрузка оператора вывода в консоль: cout << TFrac;

ostream& operator <<( ostream& os, const TFrac& f1 )

{

    if(f1.znak == false)

        os << f1.chislitel << "/" << f1.znamenatel;

    else

        os << "-" << f1.chislitel << "/" << f1.znamenatel;

    return os;

}

    //Нахождение наибольшего общего знаменателя

int gcd(int a, int b)

{

    if(a == b) return -1;

    while(a != b)

        if (a > b)

            a = a - b;

        else

            b = b - a;

    return a;

}

    //Пустой конструктор

TFrac::TFrac()

{

    this->chislitel = 0;

    this->znamenatel = 1;

    this->znak = false;

}

    //Конструктор принимающий два числовых значения

TFrac::TFrac(int a, int b)

{

        //Определяем - положительная дробь или отрицательная

    if(b == 0 || a == 0)

    {

        this->znak = false;

        this->chislitel = 0;

        this->znamenatel = 1;

    }

    else

    {

        znak = false;

        if(a < 0)

        {

            a = abs(a);

            znak = true;

        }

        if(b < 0)

        {

            b = abs(b);

            if(znak)znak = false;

            else znak = true;

        }

        int temp = gcd(a, b);

            //Если числитель равен знаменателю - дробь единичная

        if(temp == -1)

        {

            chislitel = 1;

            znamenatel = 1;

        }

            //Иначе сокращаем дробь использую наибольший общий делитель

        else

        {

            chislitel = a / temp;

            znamenatel = b / temp;

        }

    }

}

    //Конструктор принимающий строковое представление простой дроби в //формате: "числитель"/"знаменатель"

TFrac::TFrac(QString drob)

{

        //Приводим строковое представление в числовое представление

    bool ok = true;

    int posRazdel = drob.indexOf("/");

    QString tempChislitel = drob.left(posRazdel);

    QString tempZnamenatel = drob.right(drob.length() - posRazdel - 1);

    int a = tempChislitel.toInt(&ok, 10);

    int b = tempZnamenatel.toInt(&ok, 10);

        //Выполняем операции стандартного конструктора, принимающего два числовых значения

    if(b == 0 || a == 0)

    {

        chislitel = 0;

        znamenatel = 1;

    }

    else

    {

        znak = false;

        if(a < 0)

        {

            a = abs(a);

            znak = true;

        }

        if(b < 0)

        {

            b = abs(b);

            if(znak)znak = false;

            else znak = true;

        }

        int temp = gcd(a, b);

            //Если числитель равен знаменателю - дробь единичная

        if(temp == -1)

        {

            chislitel = 1;

            znamenatel = 1;

        }

            //Иначе сокращаем дробь использую наибольший общий делитель

        else

        {

            chislitel = a / temp;

            znamenatel = b / temp;

        }

    }

}

    //Перегрузка оператора присваивания

TFrac& TFrac::operator =(const TFrac &f1)

{

    if(this != &f1)

    {

        this->chislitel = f1.chislitel;

        this->znamenatel = f1.znamenatel;

        this->znak = f1.znak;

    }

    return *this;

}

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

TFrac operator +(const TFrac &f1, const TFrac &f2)

{

        //Если знаменатели дробей равны

    if(f1.znamenatel == f2.znamenatel)

    {

            //Обе дроби положительные

        if(f1.znak == false && f2.znak == false)

            return TFrac(f1.chislitel + f2.chislitel, f1.znamenatel);

            //Обе дроби отрицательные