Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Перегрузка процедур и функций






В некоторых случаях возникает необходимость в написании подпрограмм, которые выполняют одинаковые логические действия, но над переменными разных типов данных. Например:

procedure IncrementInteger(var Value: Integer);

procedure IncrementReal(var Value: Real);

В языке Delphi существует возможность дать двум и более процедурам (функциям) одинаковые идентификаторы при условии, что все такие процедуры (функции) отличаются списком параметров. Такая возможность называется перегрузкой. Для указания того, что процедура (функция) перегружена, служит стандартная директива overload. С ее помощью вышеприведенный пример можно переписать следующим образом:

procedure Increment(var Value: Integer); overload; // процедура 1

procedure Increment(var Value: Real); overload; // процедура 2

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

var

X: Integer;

Y: Real;

begin

X: =1;

Y: =2.0;

Increment(X); // Вызывается процедура 1

Increment(Y); // Вызывается процедура 2

end.

При перегрузке процедур и функций существует особенность, связанная с целочисленными типами данных. Допустим, имеются две процедуры:

procedure Print(X: Shortint); overload; // процедура 1

procedure Print(X: Longint); overload; // процедура 2

Если мы попробуем вызвать процедуру Print, указав в качестве фактического аргумента целочисленную константу, то увидим, что выбор компилятором варианта процедуры зависит от значения константы.

Print(5); // Вызывается процедура 1

Print(150); // Вызывается процедура 2

Print(-500); // Вызывается процедура 2

Print(-1); // Вызывается процедура 1

Очевидно, что одно и то же число может интерпретироваться и как Longint, и как Shortint (например, числа 5 и -1). Логика компилятора в таких случаях такова: если значение фактического параметра попадает в диапазон значений нескольких типов, по которым происходит перегрузка, то компилятор выбирает процеудуру (функцию), у которой тип параметра имеет меньший диапазон значений. Например, вызов Print(5) будет означать вызов того варианта процедуры, который имеет тип параметра Shortint. А вот вызов Print(150) будет означать вызов того варианта процедуры, который имеет тип параметра Longint, т.к. число 150 не вмещается в диапазон значений типа данных Shortint.

Поскольку в нынешней версии среды Delphi обощенный тип данных Integer совпадает с фундаментальным типом данных Longint, следующий вариант перегрузки является ошибочным:

procedure Print(X: Integer); overload;

procedure Print(X: Longint); overload; // Ошибка!

Такая же ошибка возникает при использовании пользовательских типов данных, определенных через общий базовый тип.

type

TMyInteger = Integer;

 

procedure Print(X: Integer); overload;

procedure Print(X: TMyInteger); overload; // Ошибка!

Что делать в тех случаях, когда такая перегрузка просто необходима? Для этого пользовательский тип данных необходимо создавать с использованием ключевого слова type:

type

TMyInteger = type Integer;

 

procedure Print(X: Integer); overload;

procedure Print(X: TMyInteger); overload; // Правильно

Необходимо заметить, что при использовании перегруженных процедур (функций), у которых есть параметры, имеющие стандартные значения, нужно быть очень внимательным, т.к. могут возникнуть ситуации, когда компилятор просто не будет знать, какую именно процедуру (функцию) вы хотите вызвать. Например:

procedure Increment(var Value: Real; Delta: Real = 1.0); overload; // процедура 1

procedure Increment(var Value: Real); overload; // процедура 2

Вызов процедуры Increment с одним параметром вызовет неоднозначность:

var

X: Real;

begin

Increment(X, 10); // Вызывается процедура 1

Increment(X); // Ошибка! Неоднозначность

end.

Запрещается также перегружать функции, которые отличаются лишь типом возвращаемого значения.

function SquareRoot(X: Integer): Single; overload;

function SquareRoot(X: Integer): Double; overload; // Ошибка!






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.