/
n-dimens
/
pascalabcnet
Обзор
Документация
Войти
/
n-dimens
/
pascalabcnet
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
PABCNetHelp/LangGuide/Classes/operoverloading.html
145 строк
9 KB
samuraiGH
adding working-tree-encoding attribute (#3325)
07 ноя 2025, 16:12
Не верифицирован
07 ноя 2025, 16:12
cf1fd29
Код
Авторство
О чём код?
<html> <head> <object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e"> <param name="Keyword" value="operator"> <param name="Keyword" value="implicit"> <param name="Keyword" value="explicit"> <param name="Keyword" value="Перегрузка операций"> </object> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title></title> <link rel="StyleSheet" href="../../default.css"> <style type="text/css"> .auto-style1 { color: #000080; } </style> </head> <body> <H1>Перегрузка операций</H1> <p>Перегрузка операций - это средство языка, позволяющее вводить операции над типами, определяемыми пользователем. В <b>PascalABC.NET</b> можно использовать только предопределенные значки операций. Перегрузка операций для типа <code>T</code>, являющегося классом или записью, осуществляется при помощи статической (классовой) функции-метода со специальным именем <b><code>operator</code></b> <i> ЗнакОперации</i>. Перегрузка специальных операций <code>+=</code>, <code> -=</code>, <code>*=</code>, <code>/=</code> осуществляется с помощью статической процедуры-метода, первый параметр которой передается по ссылке.</p> <p>Например:</p> <blockquote> <p><code><b>type</b> <br> Complex = <b>record</b><br> re,im: real;<br> <strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator</b>+(a,b: Complex): Complex; <br> <b>begin</b><br> Result.re := a.re + b.re;<br> Result.im := a.im + b.im; <br> <b>end</b>; <br> <strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator</b>=(a,b: Complex): boolean; <br> <b>begin</b><br> Result := (a.re = b.re) <b>and</b> (a.im = b.im);<br> <b>end</b>; <br> <b>end</b>;</code></p> </blockquote> <p>Для перегрузки операций действуют следующие правила:</p> <ol> <li>Перегружать можно все операции за исключением <code>@</code> (взятие адреса), <b><code>as</code></b>, <code><b>is</b></code>, <code>new</code>. Кроме того, можно перегружать специальные бинарные операции <code>+=</code>, <code>-=</code>, <code>*=</code>, <code>/=</code>, не возвращающие значений.</li> <li>Перегружать можно только еще не перегруженные операции.</li> <li>Тип по крайней мере одного операнда должен совпадать с типом класса или записи, внутри которого определена операция.</li> <li>Перегрузка осуществляется с помощью статической функции-метода, количество параметров которой совпадает с количеством параметров соответствующей операции (2 - для бинарной, 1 - для унарной).</li> <li>Перегрузка операций <code>+=</code>, <code>-=</code>, <code>*=</code>, <code>/=</code> для соответствующих операторов осуществляется с помощью статической процедуры-метода, первый параметр которой передается по ссылке и имеет тип записи или класса, в котором определяется данная операция, второй - передается по значению и совместим по присваиванию с первым. Перегрузка остальных операций осуществляется с помощью статических функций-методов. </li> <li>Операции приведения типа <span lang="ru">задаются статическими функциями, у которых </span>вместо имени <span lang="ru">используется </span> <code><b>operator</b></code> <code><b>implicit</b></code> <span lang="ru"> (для неявного приведения типа) </span>и<span lang="ru">ли </span><code><b> operator</b></code> <code><b>explicit</b></code> <span lang="ru">(для явного приведения типа)</span>. </li> </ol> <p>Например:</p> <blockquote> <p><code><b>type</b> <br> Complex = <b>record</b><br> ...<br> <strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator implicit</b>(d: real): Complex;<br> <b>begin</b><br> Result.re := d;<br> Result.im := 0;<br> <b>end</b>; <br> <strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator explicit</b>(c: Complex): string;<br> <b>begin</b><br> Result := Format('({0},{1})',c.re,c.im);<br> <b>end</b>;<br> <strong>static</strong><b><span lang="en-us"> </span>procedure</b> <b>operator</b>+=(<b>var</b> c: Complex; value: Complex);<br> <b>begin</b><br> c.re += value.re; <br> c.im += value.im;<br> <b>end</b>;<br> <strong>static</strong><span lang="en-us"><b> </b> </span><b>function</b> <b>operator</b>+(c,c1: Complex): Complex;<br> <b>begin </b><br> Result.re := c.re + c1.re; <br> Result.im := c.im + c1.im; <br> <b>end</b>;<br> <b>end</b>;</code></p> </blockquote> <p>Можно перегружать операции с помощью <a href="extensionmethods.html">методов расширения</a> - в этом случае при описании подпрограммы не следует писать слово class. Например, так в системном модуле реализовано добавление числа к строке:</p> <blockquote> <p><code><strong>function</strong> operator+(str: string; n: integer): string; <strong>extensionmethod</strong>;<br><strong>begin</strong><br> result := str + n.ToString;<br><strong>end</strong>;</code></p> </blockquote> <p>Можно перегружать расширенные операции присваивания +=, -= и т.д.: </p> <blockquote> <pre><code><strong>type</strong> t0 = <strong>class </strong> x: integer; <strong>static</strong> <strong>function</strong> <strong>operator</strong>+=(a: t0; i: integer): t0; <strong>begin</strong> a.x += i; <strong>end</strong>; <strong>end</strong>; <strong>begin</strong> <strong>var</strong> t := new t0; t += 2; </code><span class="auto-style1"><font size="2"><strong>end</strong>.</font></span></pre> </blockquote> <p>Важно отметить, что если слева от расширенного присваивания находится свойство, то перегруженная форма расширенного присваивания игнорируется и само расширенное присваивание разворачивается в присваивание и соответствующую операцию: </p> <blockquote> <pre><code><strong>type</strong> t0 = <strong>class </strong> x: integer; <strong>static</strong> <strong>function</strong> <strong>operator</strong>+=(a: t0; i: integer): t0; <strong>begin</strong> a.x += i; <strong>end</strong>; <strong>end</strong>; t1 = class <strong>property</strong> p1: t0 <strong>read</strong> ...<strong> write</strong> ...; <strong>end</strong>; <strong>begin</strong> <strong>var</strong> t := new t1; t.p1 += 2; </code><span class="auto-style1"><font size="2"><strong>end</strong>.</font></span></pre> </blockquote> <p>В данном коде последний оператор расширенного присваивания принудительно развернется в </p> <blockquote> <pre><code>t.p1 := t.p1 + 2; </code></pre> </blockquote> <p>и поскольку для t0 не перегружена операция +, то компилятор выдаст ошибку.</p> </body> </html>