Лекция: Пример перегрузки операций
При определении класса в С++ имеется возможность перегружать операции для объектов этого класса. Цель перегрузки – обеспечить такие же краткие выражения для типов, определенных пользователем, какие С++ обеспечивает для встроенных типов. Однако перегрузка операций не выполняется автоматически, поэтому требуется создавать функции, осуществляющие эту перегрузку.
До выполнения второго задания необходимо изучить механизм перегрузки операций языка С++. В качестве примера создания и использования простого класса с перегрузкой операций в листинге 1.3 представлена программа, в которой создан класс Fraction (дробь) с наличием следующих возможностей:
— конструктора по умолчанию;
— конструктора, который не допускает ситуацию, когда знаменатель дроби равен нулю;
— конструктора копирования;
— деструктора;
— функции сокращения дроби;
— перегрузки операций сложения и умножения;
— функции вывода дроби на экран.
Листинг 1.3 Перегрузка операций
#include <QTextStream>
#include <conio.h>
#include <stdlib.h>
QTextStream cout(stdout);
//объявление класса дробь
class Fraction
{ int f_Numerator, //числитель
f_Denominator; //знаменатель
public:
Fraction(); //стандартный конструктор
Fraction(int, int); //конструктор c параметрами
Fraction(Fraction const&);//конструктор копирования
//перегрузка операции '='
Fraction &operator= (const Fraction &);
/* функция должна возвращать ссылку на объект, для
которого она вызвана, и принимать в качестве
параметра единственный аргумент — ссылку на
присваиваемый объект */
//перегрузка операции '+'
Fraction operator+ (const Fraction &) const;
//перегрузка операции '*'
Fraction operator* (const Fraction &) const;
~ Fraction(){};
int LeastCommonDivisor(int, int); //наименьший
//общий делитель
void reducFract(); //сокращение дроби
void printFract(); //вывод дроби
};
//определения методов класса
//конструктор по умолчанию
Fraction::Fraction()
{ f_Numerator=0; f_Denominator=1;}
//конструктор c параметрами
Fraction::Fraction(int f_Nume, int f_Denom)
{ cout.setCodec(«CP866»);
if (f_Denom == 0)
{ cout << QString::fromUtf8(«Знам-ль дроби не должен быть нулем!\n»);
exit (0);
}
f_Numerator=f_Nume; f_Denominator=f_Denom;
reducFract();
}
//конструктор копирования
Fraction::Fraction(Fraction const& m)
{ f_Numerator=m.f_Numerator;
f_Denominator=m.f_Denominator;
}
//перегрузка операции '='
Fraction &Fraction::operator= (const Fraction &a)
{ f_Numerator=a.f_Numerator;
f_Denominator=a.f_Denominator;
return *this; }
//перегрузка операции '+'
Fraction Fraction::operator+ (const Fraction &a)const
{Fraction temp(*this);
temp.f_Numerator=temp.f_Numerator*a.f_Denominator+
a.f_Numerator*temp.f_Denominator;
temp.f_Denominator=temp.f_Denominator*a.f_Denominator;
temp.reducFract();
return temp;
}
//перегрузка операции '*'
Fraction Fraction::operator* (const Fraction &a) const
{ Fraction temp(*this);
temp.f_Numerator=temp.f_Numerator*a.f_Numerator;
temp.f_Denominator=temp.f_Denominator*a.f_Denominator;
temp.reducFract();
return temp;
}
//нахождение наибольшего общего делителя для дальнейшего
//использования в функции сокращения дроби reducFract()
int Fraction::LeastCommonDivisor(int iNum1, int iNum2)
{ //для отрицательных числителей и знаменателей
if (iNum1 < 0) iNum1*=-1;
if (iNum2 < 0) iNum2*=-1;
//чтобы не было бесконечного зацикливания
if (iNum1 == 0) iNum1=1;
else while (iNum1 != iNum2)
{ if (iNum1 > iNum2) iNum1-=iNum2;
if (iNum1 < iNum2) iNum2-=iNum1;
}
return iNum1;//если iNum1==iNum2, то все равно
//что возвращать
}
//сокращение дроби
void Fraction::reducFract()
{ int LCD;
LCD=LeastCommonDivisor(f_Numerator, f_Denominator);
f_Numerator=f_Numerator/LCD;
f_Denominator= f_Denominator/LCD;
}
//вывод дроби
void Fraction::printFract()
{ if ( f_Numerator == 0) cout << f_Numerator << endl;
else if ( f_Numerator == f_Denominator)
cout << f_Numerator/f_Denominator << endl;
else cout << " "<< f_Numerator <<endl << " ---"
<<endl << " " << f_Denominator <<endl<<endl;
}
int main()
{ cout.setCodec(«CP866»);
Fraction a(2,5),b(3,6),otv;
a.printFract();
b.printFract();
cout << QString::fromUtf8("\nСложение:") << endl;
otv = a+b; otv.printFract();
cout << QString::fromUtf8("\nУмножение:") << endl;
otv=a*b; otv.printFract();
cout << QString::fromUtf8(«Введите любой символ для продолжения»);
getch();
return 0;
}
Рисунок 1.10 – Окно с результатом работы программы