pascalabcnet/PABCNetHelp/LangGuide/ProcFunc/overloading.html

144 lines
5.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Перегрузка имен">
<param name="Keyword" value="overload">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title></title>
<link rel="StyleSheet" href="../../default.css">
</head>
<body>
<H1>Перегрузка имен подпрограмм</H1>
<p>В одном <a href="../_ProgrStruct_Defs/scope.html">пространстве имен</a> может быть определено
несколько процедур или функций с одним именем, но разным количеством или типами
параметров. Имена таких процедур и функций называются перегруженными, а их
создание - <b><font color="#FF0000"> <i>перегрузкой имен</i></font></b>.
Разновидностью перегрузки имен является
<a href="../Classes/operoverloading.html">перегрузка операций</a>.</p>
<p>При вызове перегруженной процедуры или функции выбирается
та версия, у которой типы формальных параметров совпадают с типами фактических
или наиболее близки к ним. Например, если имеются описания </p>
<blockquote>
<p><code><b>procedure </b>p(b: byte);<b><br>
begin</b><br><b>end</b>;<b><br>
procedure </b>p(r: real);<b><br>
begin</b><br><b>end</b>;</code></p>
</blockquote>
<p>то при вызове <code>p(1.0)</code> будет выбрана перегруженная
версия с параметром типа <code>real</code> (точное
соответствие), а при вызове <code>p(1)</code> будет
выбрана перегруженная версия с параметром типа <code>byte</code> (при
этом произойдет преобразование фактического параметра типа <code>integer</code>
к типу <code>byte</code>).</p>
<p>Заметим, что, в отличие от Object Pascal, использовать при
перегрузке служебное слово <code><b>overload</b></code> не нужно.</p>
<p>Если ни одна версия в текущем пространстве имен не подходит к
данному вызову, то возникает ошибка компиляции. Если две и более версии одинаково хорошо подходят к данному вызову, то
также возникает ошибка компиляции,
заключающаяся в неоднозначности выбора подпрограммы.
Например, если имеются описания</p>
<blockquote>
<p><code><b>procedure </b>p(i: integer; r: real);<b><br>
begin</b><br><b>end</b>;<b><br>
procedure </b>p(r: real; i: integer);<b><br>
begin</b><br><b>end</b>;</code></p>
</blockquote>
<p>то при вызове <code>p(1,2)</code> оба
они одинаково подходят, что приводит к неоднозначности.</p>
<p>Запрещено перегружать подпрограмму другой подпрограммой с тем
же количеством и типами параметров, отличающихся лишь тем,
передается ли параметр по значению или по ссылке. Например, описания</p>
<blockquote>
<p><code><b>procedure</b> p(i: integer);</code></p>
</blockquote>
<p>и</p>
<blockquote>
<p><code><b>procedure</b> p(<b>var</b> i: integer);</code></p>
</blockquote>
<p>считаются одинаковыми.</p>
<p>Возвращаемое значение функции не участвует в
разрешении перегрузки, т.е. перегружаемые функции не могут различаться
только типами возвращаемых значений.</p>
<p>Алгоритм перегрузки имен при наличии нескольких подключенных
модулей, а также алгоритм перегрузки имен методов имеют особенности. Основная особенность этих
алгоритмов состоит в том, что они работают через границы пространств имен.</p>
<p>Поиск перегруженного
имени глобальной подпрограммы при наличии нескольких
подключенных модулей происходит во всех
модулях. При этом вначале осуществляется просмотр текущего модуля, а потом всех
модулей, подключенных в секции <code><b>uses</b></code>,
в порядке <i>справа налево</i>. Если при этом поиске находится объект, который
не может перегружать предыдущие (например, перегружается процедура, а найдено
имя переменной), то цепочка перегрузки заканчивается, и поиск наилучшей
перегруженной подпрограммы идет среди найденных до этого момента. Если в модуле,
откомпилированном позже, имеется подпрограмма с точно такими же параметрами, то
она скрывает версию из модуля, откомпилированного раньше. </p>
<p>Например, пусть основная программа подключает два модуля -
<code>un1</code> и <code>un2</code>:</p>
<p><b><font size="2">main.pas</font></b></p>
<blockquote>
<p><code><b>uses</b> un2,un1;</code></p>
<p><code><b>procedure</b> p(i: integer);<br>
<b>begin</b><br>
&nbsp; write(1);<br>
<b>end</b>;</code></p>
<p><code><b>begin</b><br>
&nbsp; p(2.2);<br>
&nbsp; p(2);<br>
<b>end</b>.</code></p>
</blockquote>
<p><b><font size="2">un2.pas</font></b></p>
<blockquote>
<p><code><b>unit</b> un2;</code></p>
<p><code><b>procedure</b> p(r: real);<br>
<b>begin</b><br>
&nbsp; write(3);<br>
<b>end</b>;</code></p>
<p><code><b>end</b>.</code></p>
</blockquote>
<p><b><font size="2">un1.pas</font></b></p>
<blockquote>
<p><code><b>unit</b> un1;</code></p>
<p><code><b>procedure</b> p(r: real);<br>
<b>begin</b><br>
&nbsp; write(2);<br>
<b>end</b>;</code></p>
<p><code><b>end</b>.</code></p>
</blockquote>
<p>В результате будет выведено <code>21</code>,
что означает, что первой была вызвана процедура <code>p</code>
из модуля <code>un1</code>.</p>
<p>Поиск перегруженного имени метода осуществляется аналогично:
вначале осуществляется просмотр текущего класса, затем его базового класса и
т.д. до класса <code>Object</code>, либо до того момента, как будет встречен
объект, который не может перегружать предыдущие (имя поля или
свойства). Из всех найденных таким образом одноименных методов выбирается
наилучший. При этом в
разных классах могут быть методы с идентичными параметрами;
в этом случае вызывается первый встреченный метод от данного
класса к классу <code>Object</code>. </p>
<p>Подпрограммы с переменным числом параметров
также участвуют в перегрузке, однако, обычные подпрограммы имеют над ними
приоритет. Например, в ситуации</p>
<blockquote>
<p><code><b>procedure</b> p(i: integer);<br>
<b>begin</b><br>
&nbsp; write(1);<br>
<b>end</b>;</code></p>
<p><code><b>procedure</b> p(<b>params</b> a: <b>array</b> <b>of</b>
integer);<br>
<b>begin</b><br>
&nbsp; write(2);<br>
<b>end</b>;</code></p>
<p><code><b>begin</b><br>
&nbsp; p(1)&nbsp; <br>
<b>end</b>.</code></p>
</blockquote>
<p>будет вызвана первая процедура.<br>
&nbsp;</p>
</body>
</html>