Копирование и сравнение объектов
Копирование и сравнение объектов возможно в двух случаях:
- типы объектов в точности совпадают;
- объекты связаны отношением наследования или имеют общий тип предка.
В последнем случае у двух объектов есть общая часть.
Сравнение
Для объектных типов поддерживаются операции сравнения на равенство и неравенство. В сравнении участвуют только значения полей объектов. Объекты считаются равными, если значения всех их полей попарно равны. Для физических объектов при сравнении физическое представление игнорируется.
Если типы сравниваемых объектов различаются, то равенство достигается только при соблюдении следующих условий:
- Типы сравниваемых объектов должны иметь общий тип предка, который, в частности, может совпадать с одним из этих типов.
- Количество полей в каждом объекте и в общем типе-предке должно совпадать.
- Значения полей сравниваемых объектов должны быть попарно равны.
Наличие или отсутствие каких-либо методов на сравнение не влияет.
Пример
ТИП А [ СТРОКА: текст; ЦЕЛОЕ: номер; ] ТИП Б(А) [ ] ТИП В(А) [ ] ТИП Г(А) [ СТРОКА: комментарий; ] ТИП Д [ СТРОКА: текст; ЦЕЛОЕ: номер; ] ВЫЧИСЛИТЬ ПЕРЕМ А: а = [ текст = "123", номер = 123 ] ПЕРЕМ Б: б = [ текст = "123", номер = 123 ] ПЕРЕМ В: в = [ текст = "123", номер = 123 ] ПЕРЕМ Г: г = [ текст = "123", номер = 123 ] ПЕРЕМ Д: д = [ текст = "123", номер = 123 ] ПЕРЕМ рез1 = а = б // ДА, общая чаcть А ПЕРЕМ рез2 = б = в // ДА, общая чаcть А ПЕРЕМ рез3 = а = г // НЕТ, в Г полей больше чем в А ПЕРЕМ рез4 = б = г // НЕТ, в Г полей больше чем в А (и Б) ПЕРЕМ рез5 = а = д // НЕТ, несвязанные типы А и Д КОНЕЦ
Копирование
Копирование всегда охватывает весь меньший объект. Это означает, что при копировании большего объекта в меньший значениями полей большего будут заполнены все поля меньшего. При копировании меньшего в больший будут скопированы все поля меньшего, а остальные поля большего объекта останутся без изменений. Сказанное относится также к индексным полям и обработчикам событий (для визуальных объектов). Копирование больших объектов может занимать заметное время, поэтому надо четко оговорить, в каких случаях оно имеет место:
- оператор присваивания по отношению к объектной переменной или контейнерной переменной, содержащей объекты;
- инициализация константой общей объектной переменной или общей контейнерной переменной, содержащей объекты;
- передача объектных параметров-значений в функции;
- передача объектных параметров-значений и параметров-переменных в программу;
- возврат результата объектного типа функцией;
- изменение значения объектной переменной-счетчика специального цикла при выполнении итераций цикла.
Следует отдельно рассмотреть вопрос об объектах, использующихся в качестве элементов индексных переменных и полей. Существует два функционально различных случая:
- объектный тип элементов явно указан при объявлении контейнерной переменной или поля;
- объекты содержатся в контейнерной переменной со смешанным типом элементов.
В первом случае при обращении к элементу создается экземпляр указанного в объявлении типа. Копирование производится в объект именно этого типа. Во втором случае тип создаваемого элемента неизвестен. Копирование в такой элемент контейнерной переменной установит тип копируемого значения. Это единственный способ создавать контейнерные переменные с разнородными объектами.
Пример
ТИП Малый [ СТРОКА: мал = "малое поле"; ] ТИП Большой(Малый) [ СТРОКА: бол = "большое поле"; ] ВЫЧИСЛИТЬ // объявляем индексную переменную объектов типа Малый ПЕРЕМ Малый: ИндМал[ЧИСЛО] // объявляем индексную переменную с элементами смешанного типа ПЕРЕМ *: ИндСм[ЧИСЛО] // объявляем переменную типа Большой ПЕРЕМ Большой: Б // объявляем переменную типа Малый ПЕРЕМ Малый: М // копируем объект типа Большой в объект типа Малый ИндМал[1] = Б // копируем объект типа Большой в объект типа Большой ИндСм[1] = Б // копируем объект типа Малый в объект типа Малый ИндСм[2] = М // копируем объект типа Малый в объект типа Большой, // т.к. элемент ИндСм[1] был создан копированием Б ИндСм[1] = М КОНЕЦ