Тверской государственный университет
Опубликован: 03.10.2011 | Доступ: свободный | Студентов: 3284 / 60 | Оценка: 4.33 / 3.83 | Длительность: 19:48:00
ISBN: 978-5-9963-0573-5
Лекция 10:

Переменные, присваивание и ссылки

9.5. Ссылочное присваивание

Значения, которыми мы манипулируем, — в частности, поля объектов, соответствующие атрибутам их классов, — могут быть базисными значениями, такими как целые и булевские, а могут быть и ссылками. До сих пор мы применяли присваивание к базисным значениям, но нам понадобится и присваивание ссылок. Это необходимо, например, при построении связанных структур данных, таких как список остановок метро, где каждая остановка содержит ссылку на связанную с ней станцию и на следующую остановку на линии.

Построение остановок метро

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

set_station (ms: STATION)
    — Связать эту остановку с ms 
  require
    station_exists: ms /= Void
  ensure
    station_set: station = ms link (s: STOP)
    — Сделать s следующей остановкой на линии
  ensure
    next_set: right = s

Реализация требует установки значений для атрибутов класса station и right, для чего необходимо присваивание. Приведем текст метода (не ограничиваясь интерфейсом):

set_station (ms: STATION)
    — Связать эту остановку с ms
  require
    station_exists: ms /= Void
  do
    station:=ms
  ensure
    _set: station = ms
  end
link (s: STOP)
    — Сделать s следующей остановкой на линии.
  do
    right := s
  ensure
    next_set: right = s
  end

Ссылочное присваивание присоединяет ссылку к новому объекту. Предыдущее значение ссылки могло быть void (объект отсутствует) или присоединено к другому объекту (могло быть даже присоединено к тому же самому объекту, и тогда присваивание ничего бы не меняло). Для иллюстрации этих возможностей рассмотрим переменные s1 и s2 типа STOP и два оператора создания:

create s1.set_station (Station_Balard)
create s2.set_station (Station_Issy)

Оба оператора используют процедуру создания set_station. Это необходимо, поскольку мы уже переписали класс STOP следующим образом:

class STOP create
  set_station
feature
  station: STATION
  right: STOP
  set_station (s: STATION) ... Как выше ...
  link (s: STOP) ... Как выше ...
invariant
  station_exists: station /= Void
end

Операторы создают два объекта:

Благодаря процедуре создания set_station ссылки на станцию присоединяются к двум предопределенным объектам типа STATION. Ссылки right остаются void, так все ссылки изначально устанавливаются в void, а set_station ничего не делает с right.

Создание двух остановок

Рис. 9.9. Создание двух остановок

Построение линии метро

Для соединения двух остановок можно использовать оператор:

s1.link(s2)

Он обновляет right-ссылку первого объекта:

Сцепление двух остановок

Рис. 9.10. Сцепление двух остановок

Результат является следствием ссылочного присваивания в процедуре link:

link (s: STOP)
    — Сделать s следующей остановкой на линии.
  do
    right:=s
  ensure
    right_set: right = s
  end

Это пример ссылочного присваивания, присоединяющего ссылку. Здесь ссылка (поле right объекта STOP слева) была до присваивания равна void; мы присвоили ей непустую ссылку s2, в результате right была присоединена ко второму STOP-объекту. Ссылочное присваивание можно использовать для отсоединения от объекта, делая ссылку пустой — void. Для примера добавим в класс STOP следующую процедуру:

make_last
  — Сделать эту остановку последней на линии.
do
  right := Void
ensure
  no_right: right = Void
end

Здесь используется значение Void, всегда обозначающее пустую ссылку. Следующие три вызова дают один и тот же эффект в предположении, что v имеет значение void:

s1.make_last    s1.link (Void)    s1.link (v)

Чтобы еще немного поиграть со ссылками, рассмотрим предыдущий пример, но уже с тремя остановками:

create s1.set_station (Station_Balard)
create s2.set_station (Station_Issy)
create s3.set_station (Station_Montrouge)
s1.link( s2) 
s2.link( s3)
s3.make_last

Результатом является дополнение предыдущего рисунка, показывающее мини-линию метро:

Создание небольшой линии метро

Рис. 9.11. Создание небольшой линии метро

9.6. Программирование со ссылками

Ссылка идентифицирует объект. Их использование дает ряд преимуществ: моделирование отношения "Знаю о", поддержка связанных структур. Но у ссылок есть и обратная, темная сторона: динамические псевдонимы заставляют быть крайне внимательными при работе со ссылками.

Ссылки как инструмент моделирования

Один объект может включать ссылку на другой объект, представляя концепцию "знаю о" (об этом объекте). Эту концепцию можно сравнить с концепцией "содержит" (другой объект). Разницу демонстрирует пример с двумя интерпретациями глагола "имеет".

  • Автомобиль имеет марку (A car has a brand).
  • Автомобиль имеет мотор (A car has an engine).

Ключевая разница в разделении: два автомобиля могут иметь одну и ту же марку, но ни один уважающий себя автомобиль не будет разделять мотор с другим автомобилем. Создавая ОО-программную модель, в первом случае используем ссылку на объект, во втором — подобъект.

Подобъекты и ссылки

Рис. 9.12. Подобъекты и ссылки

Развернутые типы помогают моделировать подобъекты. Такая гибкость моделирования крайне важна при построении модели сложной системы.

Кирилл Юлаев
Кирилл Юлаев
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?