Перегружаемые подпрограммы
В Delphi предусмотрена возможность описания нескольких подпрограмм с одинаковыми именами в одной и той же области видимости. Такие подпрограммы называются перегружаемыми.Аналогичные механизмы присутствуют в большинстве современных языков программирования.
Наличие механизма перегружаемых подпрограмм позволяет реализовы-вать подпрограммы, выполняющие одинаковые действия на основе параметров разных типов, что упрощает их вызов, так как отпадает необходимость приведения параметров к конкретным типам данных. Кроме того, перегружаемые подпрограммы могут создаваться не только с параметрами разных типов, но и вообще с разным количеством параметров.
Для того, чтобы компилятор мог выбрать правильную подпрограмму из нескольких перегруженных, они должны отличаться так называемой сигнатурой— последовательностью типов данных в списке параметров. Также перегружаемые подпрограммы должны быть помечены ключевым словом overload. Пример описания и использования перегружаемой подпрограммы приведен в листинге 4.9.
Листинг 4.9. Использование перегружаемой подпрограммы
Unit DeclaringOverloads Interface
Function GetName(A:
Implementation
(Заголовок модуля} {Указание на начало интерфейсной секции} Function GetName(S: String): String; overload;
{Заголовок функции GetName с одним строковым параметром} Integer): String; overload;
{Заголовок функции GetName с одним числовым параметром} {Указание на начало описательной секции} Uses
SysUtils; {Подключение модуля SysUtils для
доступа к функции IntToStr}
Function GetName(S: String): String; overload; begin
Result := S;
end; {Описание функции GetName с одним
строковым параметром, в качестве результата возвращается параметр}
Function GetName(A: Integer): String; overload; begin
Result := IntToStr (A); {Описание функции GetName с одним числовым параметром, в качестве результата возвращается строковое представление параметра}
end;
End. {Окончание модуля}
Досрочный выход из подпрограммы
Подпрограммы являются довольно крупными логическими единицами программы и выполняют обычно довольно сложные действия. Необходимый результат, ожидаемый от процедуры или функции — выполнение каких-либо действий или расчет возвращаемого значения — может быть получен при выполнении не всего кода подпрограммы, а только его части. Поэтому подпрограммы снабжены механизмом досрочного завершения, реализуемым процедурой Exit:
Procedure Exit;
Результатом выполнения процедуры Exit будет передача управления от подпрограммы к фрагменту программы, вызвавшему ее. Если Exit вызывается в основной части программы, а не в процедуре или функции, то завершится программа.
Необходимо отметить, что при использовании процедуры Exit в функциях следует внимательно следить за инициализацией возвращаемого значения, то есть выход из функции должен быть произведен только после его расчета, иначе вызывающий фрагмент может получить некорректные данные.
Процедурные типы данных
В заключение, мы вернемся к информационной структуре программы разберем такое важное для программирования на Delphi понятие, как процедурные типы данных.
Переменные процедурного типа представляют собой ссылки на подпрограммы — процедуры и функции. Описание типа строится на основе сигналы подпрограммы без указания имени:
<Назвзвание типа> = Procedure(<Список параметров>)
Или для функций:
Туре
<Название типа> = Function(<Список параметров>): <Возвращаемое значение>;
Допускается описание переменной в разделе Var без введения в программу нового процедурного типа, например:
Var
fSin = Function(X:Double): Double;
Как и переменные любого другого типа, процедурные переменные после описания не определены. Для инициализации процедурной переменной необходимо присвоить ей адрес подпрограммы, доступной текущему фрагменту программы, в котором выполняется присвоение. Для получения адреса подпрограммы используется ее имя:
<Название переменной> = <Название подпрограммы:*;
После инициализации переменная процедурного типа используется так же, как и вызов обычной подпрограммы, то есть вместо названия подпрограммы указывается название процедурной переменной:
<Название переменной>(<Список параметров>);
Рассмотрим пример описания процедурного типа данных, переменной на его основе, ее инициализации и использования (листинг 4.10).