Компания ALT Linux
Опубликован: 10.04.2015 | Доступ: свободный | Студентов: 763 / 0 | Длительность: 14:03:00
Специальности: Программист, Преподаватель
Лекция 9:

Объектно-ориентированное программирование

< Лекция 8 || Лекция 9: 12345 || Лекция 10 >

9.4 Перегрузка операций

В FreePascal можно перегрузить не только функции, но и операции. Например, можно запрограммировать, чтобы операция * при работе с матрицами осуществляла умножение матриц, а при работе с комплексными числами — умножение комплексных чисел.

Для этого в программе нужно написать специальную функцию — метод. Объявление метода перегрузки записывается после объявления класса и выглядит так:

operator symbols (параметры: тип) имя_переменной_результата: тип;

где

  • operator — служебное слово;
  • symbols — символ перегружаемой операции;
  • параметры — имена переменных, участвующих в перегрузке оператора.

Описывают метод перегрузки так же, как и другие методы, после ключевого слова implemention того модуля, в котором объявлен класс.

Рассмотрим несколько примеров.

ЗАДАЧА 9.1. Создать класс работы с комплексными числами, в котором перегрузить операции сложения и вычитания.

На форме разместим четыре компонента типа TEdit для ввода действительной и мнимой частей двух комплексных чисел. Также создадим компонент типа TMemo для вывода результатов и кнопку. При щелчке по кнопке создаются четыре объекта типа "комплексное число". Первое и второе числа инициализируются введенными данными. Третье формируется как результат сложения первых двух, а четвёртое — как разность этих же чисел. Текст программы с комментариями приведён ниже, на рис. 9.4 показано окно работы программы.

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
	Classes, SysUtils, LResources, Forms, Controls, Graphics,
	Dialogs, StdCtrls;
type
{ TForm1 }
	TForm1 = class (TForm)
	Button1 : TButton;
	//для ввода действительной части первого числа
	Edit1 : TEdit;
	//для ввода мнимой части первого числа
	Edit2 : TEdit;
	//для ввода действительной части второго числа
	Edit3 : TEdit;
	//для ввода мнимой части второго числа
	Edit4 : TEdit;
	Label1 : TLabel;
	Label2 : TLabel;
	Label3 : TLabel;
	Label4 : TLabel;
	Label5 : TLabel;
	Label6 : TLabel;
	Memo1 : TMemo; //поле для вывода результатов
	procedure Button1Click ( Sender : TObject );
private
	{ private declarations }
public
	{ public declarations }
end;
//объявление класса "комплексное число"
type
	TComplex = class
	private
		x : real; //действительная часть
		y : real; //мнимая часть
	public
		constructor Create; //конструктор
	function Modul ( ) : real;
	function Argument ( ) : real;
	function ComplexToStr ( ) : String;
end;
//объявление метода перегрузки
//оператора "+" с комплексными числами
	operator +(const a, b : TComplex ) r : TComplex;
//объявление метода перегрузки
//оператора "_" с комплексными числами
	operator -( const a, b : TComplex ) r : TComplex;
var
	Form1 : TForm1;
//объявление переменных типа "комплексное число"
	chislo1 : Tcomplex;
	chislo2 : TComplex;
	chislo3 : TComplex;
	chislo4 : TComplex;
implementation
//Описание конструктора.
constructor TComplex. Create;
begin
	x : = 0; y : = 0;
	inherited Create;
end;
function TComplex. Modul ( ) : real;
begin
	modul:= sqrt ( x * x+y * y );
end;
function TComplex. Argument ( ) : real;
begin
	argument := arctan ( y/x ) * 180/ pi;
end;
//Метода перегрузки оператора "+".
//переменные a и b - комплексные числа,
//которые складываются,
//r - результирующее комплексное число
operator +(const a, b : TComplex ) r : TComplex;
begin
	r :=TComplex. Create; //инициализация объекта
//Действительная часть нового комплексного
//числа формируется как результат сложения
//действительных частей первого и второго
//операндов. Мнимая часть нового комплексного
//числа формируется как результат сложения
//мнимых частей первого и второго операндов.
//Операнды - переменные типа комплексное
//число, передаваемые в метод.
	r. x:=a. x+b. x;
	r. y:=a. y+b. y;
end;
//метод перегрузки оператора "-"
operator -( const a, b : TComplex ) r : TComplex;
begin
	r :=TComplex. Create;
	r. x:=a. x-b. x;
	r. y:=a. y-b. y;
end;
function TComplex. ComplexToStr ( ) : String;
//Действительная часть нового комплексного
//числа формируется как разность действительных
//частей первого и второго операндов. Мнимая
//часть нового комплексного числа формируется
//как разность мнимых частей первого и второго
//операндов. Операнды — переменные типа
//комплексное число, передаваемые в метод.
begin
	if y>=0 then
	ComplexToStr := FloatToStrF ( x, ffFixed,5,2)+ ’+ ’ +
		FloatTostrF ( y, ffFixed,5,2)+ ’ i ’
			else
	ComplexToStr := FloatTostrF ( x, ffFixed,5,2)+
		FloatTostrF ( y, ffFixed,5,2)+ ’ i ’
end;
procedure TForm1. Button1Click ( Sender : TObject );
var Str1 : String;
begin
//инициализация объектов
	chislo1:=TComplex. Create;
	chislo2:=TComplex. Create;
	chislo3:=TComplex. Create;
	chislo4:=TComplex. Create;
//чтение действительной и мнимой частей двух исходных
//комплексных чисел с формы
	chislo1.x:= StrToFloat ( Edit1. Text );
	chislo1.y:= StrToFloat ( Edit2. Text );
	chislo2.x:= StrToFloat ( Edit3. Text );
	chislo2.y:= StrToFloat ( Edit4. Text );
//для сложения двух комплексных чисел можно использовать
//операцию "+", так как она перегружена для этого класса
	chislo3:= chislo1+chislo2;
//для вычитания двух комплексных чисел можно использовать
//операцию "_", так как она перегружена для этого класса
	chislo4:= chislo1 - chislo2;
	Str1 := ’ chislo1+chislo2  ’+chislo3. ComplexToStr ( );
	Memo1. Lines.Add( Str1 );
	Str1 := ’ Modul  chisla   ’+
	FloatToStrF ( chislo3. Modul ( ), ffFixed, 5, 2 );
Memo1.Lines.Add( Str1 );
Str1 := ’ Argument  chisla  ’+
FloatToStrF ( chislo3.Argument ( ), ffFixed, 5, 2 );
Memo1. Lines.Add( Str1 );
Str1 := ’ chislo1-chislo2  ’+chislo4. ComplexToStr ( );
Memo1. Lines.Add( Str1 );
Str1 := ’ Modul  chisla  ’+
FloatToStrF ( chislo4.Modul ( ), ffFixed, 5, 2 );
Memo1. Lines. Add( Str1 );
Str1 := ’ Argument  chisla  ’+
FloatToStrF ( chislo4.Argument ( ), ffFixed, 5, 2 );
Memo1. Lines.Add( Str1 );
end;
initialization
	{$I unit1.lrs}
end.
Пример работы программы к задаче 9.1

Рис. 9.4. Пример работы программы к задаче 9.1
< Лекция 8 || Лекция 9: 12345 || Лекция 10 >
Юрий Шутиков
Юрий Шутиков

По первому тесту выполнил дважды задания. Результат получается правильный (проверял калькулятором). Пишет, что "Задание не проверено" и предлагает повторить. 
 

Евгений Силуков
Евгений Силуков

Еще в декабре выполнил тест №1, а его все так и не проверили.