Студопедия

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

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

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






Глубокое клонирование и сравнение






 

Формы копирования и сравнения, реализуемые подпрограммами clone, equal и copy, называются поверхностными, поскольку они работают с объектами только на первом уровне, никогда не пытаясь следовать вглубь по ссылкам. Возникает необходимость для глубоких вариантов этих операций, рекурсивно дублирующих полную структуру.

Для понимания разницы рассмотрим пример, показанный на рис.8.16. Предположим, что мы начинаем в начальном состоянии A, где сущность a присоединена к объекту O1.

Рис. 8.16. Различные формы присваивания и клонирования

Рассмотрим простое присваивание ссылки:

 

b: = a

 

В состоянии B, показанном на рисунке, цель b в результате присваивания присоединена к объекту O1, к которому присоединен источник a. Никаких новых объектов не создается.

Далее рассмотрим операцию клонирования:

 

c: = clone (a)

 

Эта инструкция, как показывает раздел C нашего рисунка, создает новый объект O4, с полями, идентичными полям объекта O1. Будут скопированы два ссылочных поля, и значения ссылок будут указывать на те же объекты O1 и O3, как и поля оригинального объекта O1. Но, заметьте, не происходит дублирования самого объекта O3, и никакого другого объекта помимо дублирования O1. По этой причине базисная операция clone называется поверхностным клонированием, - она останавливается на первом уровне объектной структуры.

Заметьте, при клонировании исчезли ссылки на себя. Ссылка landlord объекта O1 была присоединена к самому объекту O1. У объекта O4 это поле становится ссылкой на оригинал O1. В некоторых ситуациях вы, возможно, захотите пойти дальше и дублировать структуру рекурсивно без введения разделяемых ссылок. Функция глубокого клонирования deep_clone позволяет достичь цели. Процесс создания deep_clone (y) рекурсивно следует за всеми ссылочными полями, содержащимися в объекте, дублируя полную структуру. (Если y это void, то и результат будет также void.) Эта функция будет, конечно же, правильно обрабатывать циклические ссылочные структуры.

Нижняя часть на рисунке - раздел D - иллюстрирует выполнение этой операции:

 

d: = deep_clone (a)

 

В этом случае не появляются новые разделяемые ссылки. Все объекты, прямо или косвенно доступные объекту O1, будут дублированы, создавая новые объекты O5, O6 и O7. Нет никаких связей между старыми объектами (O1, O2 и O3) и новыми. Объект O5, дублирующий O1, имеет собственные ссылки на себя.

Так же, как необходимы операции глубокого и поверхностного клонирования, необходимо иметь глубокий вариант эквивалентности. Функция deep_equal сравнивает две объектные структуры, определяя их структурную идентичность. В примере, показанном на рисунке, deep_equal выполнимо для любой пары из a, b и d. В то же время equal (a, c) истинно, поскольку поля объектов O1 и O4 идентичны, equal (a, d) - ложно. Фактически equal не выполнимо ни для одной пары из d и любого элемента оставшейся тройки. В целом имеют место следующие свойства:

[x]. В результате присваивания x: = clone (y) или вызова x.copy (y), выражение equal (x, y) имеет значение true (в случае присваивания это свойство имеет место независимо от того, имеет ли y значение void).

[x]. В результате присваивания x: = deep_clone (y), выражение deep_equal (x, y) имеет значение true.

Эти свойства будут отражены в постусловиях соответствующих подпрограмм.

 

Глубокое хранилище: первый взгляд на сохраняемость

 

Изучение глубокого копирования и эквивалентности приводит к механизму, обеспечивающему серьезные практические преимущества ОО-метода, естественно, при условии его доступности в среде разработки.

До сих пор обсуждение не затрагивало вопросов ввода и вывода. Но, конечно, ОО-системе необходимо общаться с внешним миром и другими системами. Такое общение предполагает возможность чтения и записи объектов в различные хранилища - файлы, базы данных, сеть.

Для простоты в этом разделе будем предполагать, что проблема сводится к чтению и записи файлов. Для этих операций будем использовать термины " возвратить" (retrieval) и " сохранить" (storage), адекватные терминам ввод и вывод (input, output). Изучаемые механизмы должны быть применимыми при использовании других средств коммуникации, например при посылке и получении объектов по сети. Для экземпляров таких классов, как POINT или BOOK1 сохранение и возвращение объектов не является какой-либо новинкой. Эти классы, используемые в качестве первых примеров этой лекции, имеют атрибуты таких типов, как INTEGER, REAL и STRING, для которых доступно хорошо понятное внешнее представление. Сохранение или возвращение экземпляра такого класса из файла подобно выполнению операций ввода-вывода записей в языке Паскаль или структур языка С. Для этих хорошо известных технических проблем существуют стандартные решения. Поэтому резонно ожидать, что объектам в хорошем ОО-окружении можно предоставить процедуры общего назначения, скажем read и write, которые подобно clone и copy будут доступны для всех классов.

Но такие механизмы не могут нас полностью устраивать, поскольку они не управляют главным элементом объектной структуры - ссылками. Так как ссылки могут быть представлены адресами памяти или чем-то подобным, то и для них можно найти подходящее внешнее представление. Это не самая трудная часть проблемы. Сложнее обстоит дело с передачей смысла самих ссылок. Ссылки присоединены к объектам и бесполезны в отсутствие этих объектов. Так что, как только мы начинаем иметь дело с нетривиальными объектами - объектами, содержащими ссылки, нас перестают устраивать старые механизмы сохранения и возвращения, работающие только со значениями. Механизмы должны вместе с объектом обрабатывать и всех его связников (dependents) в соответствии со следующим определением:

Определение: связники, прямые связники






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