Бертран Мейер - Основы объектно-ориентированного программирования
- Название:Основы объектно-ориентированного программирования
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Бертран Мейер - Основы объектно-ориентированного программирования краткое содержание
Фундаментальный учебник по основам объектно-ориентированного программирования и инженерии программ. В книге подробно излагаются основные понятия объектной технологии – классы, объекты, управление памятью, типизация, наследование, универсализация. Большое внимание уделяется проектированию по контракту и обработке исключений, как механизмам, обеспечивающим корректность и устойчивость программных систем.
В книге Бертрана Мейера рассматриваются основы объектно-ориентированного программирования. Изложение начинается с рассмотрения критериев качества программных систем и обоснования того, как объектная технология разработки может обеспечить требуемое качество. Основные понятия объектной технологии и соответствующая нотация появляются как результат тщательного анализа и обсуждений. Подробно рассматривается понятие класса - центральное понятие объектной технологии. Рассматривается абстрактный тип данных, лежащий в основе класса, совмещение классом роли типа данных и модуля и другие аспекты построения класса. Столь же подробно рассматриваются объекты и проблемы управления памятью. Большая часть книги уделена отношениям между классами – наследованию, универсализации и их роли в построении программных систем. Важную часть книги составляет введение понятия контракта, описание технологии проектирования по контракту, как механизма, обеспечивающего корректность создаваемых программ. Не обойдены вниманием и другие важные темы объектного программирования – скрытие информации, статическая типизация, динамическое связывание и обработка исключений. Глубина охвата рассматриваемых тем делает книгу Бертрана Мейера незаменимой для понимания основ объектного программирования.
Основы объектно-ориентированного программирования - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Для сложных структур данных нам нужен третий и последний режим: динамическая память, называемая также "кучей", из-за способа ее использования. Это память, в которой объекты создаются динамически по запросу. Сущности могут динамически присоединяться к разным объектам. Во время компиляции обычно нельзя предсказать, какие объекты будут созданы и присоединены к сущности. Кроме того, объекты могут содержать ссылки на другие объекты.
Рис. 9.3. Динамический режим
Динамическая память позволяет создавать сложные динамические структуры данных, необходимые когда, как обсуждалось в предыдущей лекции, ПО требуется вся мощь методов моделирования.
Использование динамического режима
Динамический режим, очевидно, наиболее общий, и он необходим для ОО-программирования. Его используют многие не ОО-языки. В частности:
[x].Pascal использует статический режим для массивов, режим, основанный на стеке, для переменных, не являющихся массивами и указателями, динамический режим для указателей. В последнем случае создание объекта выполняется с помощью вызова специальной процедуры создания new .
[x].Язык C похож на Pascal, но дополнительно вводит динамические массивы и статические переменные, не являющиеся массивами, Язык С динамически размещает переменные типа указатель и массивы, используя библиотечную функцию malloc .
[x].PL/I поддерживает все модели.
[x].Lisp системы традиционно были высоко динамичны и полагались большей частью на динамический режим распределения памяти. Одна из наиболее важных операций Lisp, используемая многократно для представления списков, - CONS , создает структуру из двух полей. В первом поле хранится значение элемента, а во втором - указатель на следующий элемент. Здесь CONS , скорее источник новых объектов, чем инструкция их создания.
Повторное использование памяти в трех режимах
Для объектов, созданных как в основанном на стеке режиме, так и в динамическом режиме, возникает вопрос, что делать с неиспользуемыми объектами? Возможно ли память, занятую таким объектом, повторно использовать в более поздних инструкциях создания новых объектов?
В статической модели проблемы не существует: для каждого объекта есть одна навсегда присоединенная сущность. Выполнение требует поддерживать связь с объектом все время, пока сущность активна. Поэтому повторное использование памяти невозможно в настоящей трактовке этого понятия. Однако при острой нехватке памяти похожая технология иногда используется. Если вы уверены, что объекты, присоединенные к двум сущностям, никогда не нужны одновременно, и эти сущности не должны сохранять свои значения между последовательными использованиями, то можно на одной и той же памяти размещать две или более сущности, будучи совершенно увереными в безопасности того, что вы делаете. Эта техника, известная как перекрытие (overlay), достаточно ужасная, все еще практикуется при работе вручную.
Если все-таки использовать перекрытие, то, конечно, его следует выполнять автоматически, используя специальные инструменты, - слишком велика вероятность ошибки. Главной проблемой остается возможность изменений: решение о перекрытии двух переменных может быть корректным на определенном этапе жизни программы. Неожиданное изменение может сделать его неправильным. Мы столкнемся с похожей проблемой ниже, в технологии сборки мусора. |
В режиме, основанном на стеке, объекты, присоединенные к сущностям, могут быть размещены в стеке. В языках с блочной структурой ситуация упрощается: размещение объектов происходит одновременно для всех сущностей данного блока, допуская использование одного стека для всей программы. Схема действительно элегантна, потому что использует два множества сопутствующих событий:
Динамическое свойство (событие времени выполнения) | Статическое свойство (положение в тексте программы) | Техника реализации |
---|---|---|
Размещение объекта | Начало блока | Вталкивание объектов (один для каждой локальной сущности блока) в стек |
Удаление объекта | Конец блока | Выталкивание объектов из стека |
Таблица 9.1.Размещение и удаление объектов в языках с блочной структурой
Простота и эффективность этой техники реализации является одной из причин успешности языков с блочной структурой. В динамическом режиме все не так просто. Проблема связана с мощью самого механизма: в период компиляции ничего нельзя сказать о создании объекта, невозможно предсказать, когда данный объект может стать ненужным.
Отсоединение
В динамическом режиме объекты могут стать ненужными в непредсказуемые моменты периода выполнения; раз так, то некоторый механизм (определяемый позже в этом обсуждении) может освобождать занятую ими память.
Причина - присутствие в этом режиме выполнения операции отсоединения (detachment), обратной к операции присоединения. В предыдущей лекции изучалось, как сущности присоединяются к объектам, но не рассматривались детали отсоединения. Пора это исправить.
Отсоединение распространяется только на объекты x ссылочного типа. Если x развернутого типа - значением x является объект O, то нет способа отсоединить x от O. Заметьте, однако, если x развернутый атрибут некоторого класса, O представляет подобъект некоторого большого объекта BO. Тогда BO, а вместе с ним и O, может стать недостижимым по одной из причин, изучаемых ниже. Посему в оставшейся части этой лекции можно ограничиться рассмотрением сущностей ссылочного типа. |
Рис. 9.4. Отсоединение
Основные причины отсоединения следующие. Предположим, x и y сущности ссылочного типа вначале присоединены к объектам O1 и O2. Рисунок иллюстрирует случаи D1 и D2.
[x].(D1) Присваивание вида x := Void , или x := v где v типа void , отсоединяет x от O1.
[x].(D2) Присваивание вида y := z , где z не присоединен к объекту O2, отсоединяет y от O2.
[x].(D3) Завершение подпрограммы отсоединяет формальные аргументы от присоединенных к ним объектов.
[x].(D4) Инструкция создания create x , присоединяет x к вновь созданному объекту и, следовательно, отсоединяет x , если он ранее был присоединен к объекту O1.
Случай D3 соответствует ранее данному правилу: инициализация формального аргумента a подпрограммы r во время вызова t.r(..., b, ...) , где позиция b в вызове соответствует позиции a в объявлении r , в точности соответствует семантике присваивания a := b .
Читать дальшеИнтервал:
Закладка: