Языки программирования — Осенний семестр; Михалкович С.С.; 2008 — различия между версиями
Admin (обсуждение | вклад) (→Лекция 3 (16.09.08)) |
Admin (обсуждение | вклад) (→Лекция 4 (23.09.08)) |
||
Строка 71: | Строка 71: | ||
Идея ускорения доступа. Хеширование. Хеш-таблица, хеш-функция. | Идея ускорения доступа. Хеширование. Хеш-таблица, хеш-функция. | ||
+ | |||
+ | ==Лекция 5 (30.09.08)== | ||
+ | |||
+ | Реализация множества на основе хеш-таблицы. | ||
+ | |||
+ | Класс Ассоциативный массив на PascalABC.NET на основе списка. | ||
+ | |||
+ | Классы ассоциативных массивов в стандартной библиотеке NET. Итератор ассоциативного массива. Цикл foreach по ассоциативному массиву. | ||
+ | |||
+ | Контейнерные классы в Java: обзор. Классы-обертки (Integer, Double). | ||
+ | |||
+ | Стандартный класс двусвязного списка в библиотеке Java. Итератор списка. Итерация по списку. | ||
+ | |||
+ | Пакеты в Java. Пример использования пакетов. | ||
+ | |||
+ | ==Лекция 6 (07.10.08)== | ||
+ | |||
+ | Библиотеки в PascalABC.NET. Многоязыковость. Отличие библиотек от модулей. | ||
+ | |||
+ | Библиотеки JAR в Java. | ||
+ | |||
+ | Перегрузка операций в C++ - общие правила. | ||
+ | |||
+ | Класс Date. Перегрузка операций +, +=, ++ (префиксной и постфиксной), ==, !=. | ||
+ | |||
+ | Дружественные функции в C++. | ||
+ | |||
+ | ==Лекция 7 (14.10.08)== | ||
+ | |||
+ | Перегрузка операций << и >> | ||
+ | |||
+ | С++: выделение динамической памяти в конструкторе (на примере класса myvector). | ||
+ | |||
+ | Перегрузка операции []. | ||
+ | |||
+ | Деструкторы. Момент вызова деструктора. | ||
+ | |||
+ | Динамический массив в динамической памяти. Момент вызова конструктора и деструктора. | ||
+ | |||
+ | Моделирование ссылочной модели данных средствами C++. | ||
+ | |||
+ | Конструктор копии. КК, генерируемый по умолчанию. Когда его не достаточно. | ||
+ | |||
+ | Операция присваивания. Операция присваивания, генерируемая по умолчанию. | ||
+ | |||
+ | Ситуации, в которых вызывается конструктор копии. | ||
+ | |||
+ | ==Лекция 8 (21.10.08)== | ||
+ | |||
+ | Шаблон класса myvector<T>. Особенности компиляции шаблонов. Где надо размещать описания шаблонов и почему. | ||
+ | |||
+ | Описание функции-члена вне интерфейса класса. | ||
+ | |||
+ | Понятие инстанцирования шаблона класса. Два уровня ошибок компиляции шаблонов: при компиляции собственно шаблона и в момент инстанцирования шаблона. | ||
+ | |||
+ | Массив объектов класса и роль конструктора по умолчанию. | ||
+ | |||
+ | Операция (). Примеры: реализация класса matrix и объекты-функции. Преимущества объектов-функций. | ||
+ | |||
+ | ==Лекция 9 (28.10.08)== | ||
+ | |||
+ | Класс frac. Конструктор преобразования и операция приведения типа. | ||
+ | |||
+ | Ключевое слово explicit и запрет неявного преобразования. | ||
+ | |||
+ | Перегрузка операций в PascalABC.NET (на примере класса Frac). | ||
+ | Агрегация класов и подобъекты (C++). | ||
+ | |||
+ | Вызов конструктора подобъекта. | ||
+ | |||
+ | Роль конструктора по умолчанию. | ||
+ | |||
+ | Порядок вызова конструкторов и деструкторов. | ||
+ | |||
+ | Клонирование и присваивание объектов в языках со ссылочной моделью хранения объектов (на примере PascalABC.NET) | ||
+ | |||
+ | ==Лекция 10 (11.11.08)== | ||
+ | |||
+ | Наследование. | ||
+ | Основные определения: базовый класс-производный класс, предок-потомок, надкласс-подкласс. Цели наследования. Описание на PABC.NET классов Student и SeniorSudent (наследник Student). | ||
+ | |||
+ | Наследование - это расширение или сужение? | ||
+ | Наследование - это расширение интерфейса класса, но сужение количества представителей. | ||
+ | |||
+ | Переопределение и замещающие функции (PABC.NET). | ||
+ | Ключевое слово inherited. | ||
+ | |||
+ | Вызов конструктора предка в конструкторе потомка (PABC.NET). | ||
+ | Конструктор для SeniorSudent. Рекомендуется вызывать конструкторы предков первыми в конструкторе потомка, т.к. объект предка д.б. создан перед какими-то следующими действиями. В большинстве языков программирования конструкторы предка вызываются первыми принудительно. В качестве примера написали классы Queue<T> и CountingQueue<T> (наследник Queue с одним дополнительным полем - количеством элементов). | ||
+ | |||
+ | Принцип "Открыт-закрыт". | ||
+ | "Код должен быть закрыт от изменения своего текста, но открыт для модификации своего поведения." Причины закрытия и открытия кода. | ||
+ | |||
+ | Наследование и включение. | ||
+ | Понятие включения (физического и логического). Изображение отношений наследования и включения на UML-диаграммах. | ||
+ | |||
+ | Что выбрать — наследование или включение? | ||
+ | Напишем классы Queue<T> и CountingQueue<T> с использованием включения (PABC.NET). Понятие делегирования. Достоинства наследования. Пример плохого использования наследования: | ||
+ | |||
+ | Код: | ||
+ | |||
+ | Circle = class( Point ); | ||
+ | |||
+ | В обоих классах есть реализация конструктора и процедуры Draw. | ||
+ | |||
+ | Примеры с неоднозначным выбором наследования или включения. | ||
+ | |||
+ | ==Лекция 11 (18.11.08)== | ||
+ | |||
+ | Наследование и выявление общего предка. | ||
+ | Даны UML-нотации классов Student и Teacher. Заметим, что у них есть общие поля и методы. Решаем вынести их в базовый класс Person. Реализовали класс Teacher на Java, в т. ч. конструктор c super(...). | ||
+ | |||
+ | Вид доступа protected. | ||
+ | Что значит protected. protected нарушает инкапсуляцию. Пример наследования Square от Rectangle на PABC.NET. Приходим к выводу, что иногда необходимо обращаться к полям и в этом случае следует использовать protected. | ||
+ | |||
+ | Класс Object — предок всех классов. | ||
+ | Дан интерфейс класса Object в Java и .NET (не полный - из 4 и 3 методов соответственно). | ||
+ | |||
+ | Присваивание в иерархии Предок–потомок. | ||
+ | Описаны переменные s (Student) и p (Person). Пытаемся одному присвоить другое. Делаем вывод, что переменная производного класса может быть неявно преобразована к типу базового класса, но не наоборот. Рассматриваем случай явного приведения типов. Вводятся понятия UpCast и DownCast. | ||
+ | |||
+ | Операции is и as (PABC.NET) и instanceof (Java). | ||
+ | Определения статического и динамического типа переменной. | ||
+ | |||
+ | Два варианта использования операций is и as. | ||
+ | 1. | ||
+ | |||
+ | Код: | ||
+ | |||
+ | if p is Student then // не точное совпадение типов, а то, является ли p разновидностью Student | ||
+ | |||
+ | Student(p).ChangeCourse(4); | ||
+ | |||
+ | Код: | ||
+ | |||
+ | if( p instanceof Student ) | ||
+ | |||
+ | ((Student)p).changeCourse(4); | ||
+ | |||
+ | 2. | ||
+ | |||
+ | Код: | ||
+ | |||
+ | var s: Student := p as Student; | ||
+ | |||
+ | Код: | ||
+ | |||
+ | Student st = (Student) p; | ||
+ | |||
+ | Аналог операции is (instanceof), обеспечивающий точное соответствие типов. | ||
+ | |||
+ | На PABC.NET и Java. | ||
+ | |||
+ | ==Лекция 12 (25.11.08)== | ||
+ | |||
+ | Наследование в С++. | ||
+ | Вспомним наш излюбленный пример наследования на примере классов Person и Student. В предположении, что класс Person уже описан, опишем на С++ класс Student. Одно из полей Student типа char*. Понятие публичного наследования. Особенности вызова конструктора (деструктора) предка в конструкторе (деструкторе) потомка. | ||
+ | Пример использования char* надуман! Не пытайтесь повторить это дома! | ||
+ | |||
+ | Совместимость по присваиванию и преобразование типов в иерархии Предок–Потомок. | ||
+ | Описали переменные p (Person) и s (Student). Они хранятся на стеке (размерная модель). Пытаемся присвоить одному другое. Делаем вывод об отбрасывании дополнительных полей производного класса при присваивании. | ||
+ | |||
+ | Совместимость по присваиванию для типов указателей и ссылок. | ||
+ | Присвоение указателям (ссылкам): UpCast - неявно, DownCast - только явно (с помощью операции static_cast). | ||
+ | |||
+ | Конструктор копии и оператор присваивания для класса Student. | ||
+ | |||
+ | Полиморфизм и виртуальные функции. | ||
+ | (Java) Пусть в классах Person и Student есть метод print(). | ||
+ | |||
+ | Замещение (переопределение) методов. | ||
+ | |||
+ | Код: | ||
+ | |||
+ | Person p = new Student(...); p.print(); | ||
+ | |||
+ | Метод print() какого класса будет вызван? В Java - класса Student, а в OP и C++ (по умолчанию) - класса Person. Понятия раннего и позднего связывания. | ||
+ | |||
+ | Реализация позднего связывания на OP. | ||
+ | Виртуальные методы. Модификатор virtual и ключевое слово override. Определение полиморфизма. | ||
+ | |||
+ | Реализация полиморфизма в С++. | ||
+ | Аналогично в классах Person и Student описан метод print(). Присвоим объекту класса Person объект класса Student и вызовем для него метод print(). Вызовется print() класса Person. Сделаем метод виртуальным (virtual в заголовке). Все равно будет вызван метод класса Person. Причина: при присваивании происходит отбрасывание дополнительных полей и потеря информации о типе. Выход: полиморфизм в С++ работает только через указатели или ссылки на базовый класс. | ||
+ | |||
+ | В Java все методы (за исключением статических) виртуальные. | ||
+ | |||
+ | ==Лекция 13 (02.12.08)== | ||
+ | |||
+ | Виртуальные функции как блоки для замены кода. | ||
+ | 1. При разработке базового класса надо думать о будущем коде. | ||
+ | 2. Полиморфизм заставляет работать уже откомпилированный код совершенно по-другому. | ||
+ | Определение полиморфного объекта (объекта, обладающего полиморфным поведением), полиморфной подпрогораммы. | ||
+ | |||
+ | Виртуальные методы в классе Object. | ||
+ | В С++ нет класса, базового для всей иерархии классов. | ||
+ | Рассмотрели пример переопределения метода ToStrintg класса Object на PABC.NET. | ||
+ | |||
+ | Цепочки виртуальности и ее разрыв. | ||
+ | Определение цепочки виртуальности. Алгоритм поиска в цепочке виртуальности метода, который следует вызывать. Разрыв цепочки виртуальности. Идентификатор reintroduce (NET). | ||
+ | |||
+ | С++ - виртуальные деструкторы | ||
+ | Конструкторы в С++ виртуальными быть не могут, а деструкторы могут. | ||
+ | Правило: Если в классе есть хотя бы одна виртуальная функция или нет, но в подклассах они могут появиться, то деструктор этого класс следует сделать виртуальным. | ||
+ | Правило: Если деструктор базового класса виртуальный, то сгенерированный деструктор также будет виртуальным. | ||
+ | |||
+ | |||
+ | |||
+ | Полиморфные контейнеры | ||
+ | |||
+ | Полиморфный контейнер в .NET | ||
+ | Рассмотрели пример на PABC.NET в котором Shape - это предок классов геометрических фигур. Хотим написать методы Draw и Hide. Вместо этого (вместе с этим) дали определение абстрактного метода и абстрактного класса. Идем дальше. Реализовали класс Shape. В глаза бросается метод MoveTo, который вызывает два абстрактных виртуальных метода (Hide и Draw). Интересно, он вообще работает... Ответ: да, работает, ведь перед Hide и Draw неявно стоит self - ссылка, - как раз то, что надо для виртуальных методов. | ||
+ | Заполнили List<Shape> объектами производного от Shape класса, в одном цикле foreach нарисовали их, в другом переместили. | ||
+ | Определение полиморфного контейнера. | ||
+ | Если класс абстрактный, то объекты этого класса создавать нельзя. | ||
+ | |||
+ | Полиморфный контейнер на С++. | ||
+ | Написали тот же класс Shape на С++. Здесь Hide и Draw называются уже чисто виртуальными ( =0 ). Затем заполнили vector<Shape*> объектами производного класса, в цикле (с итератором) нарисовали их, а потом еще и переметили на заданный ветктор. Полиморфное клонирование в полиморфном контейнере. | ||
+ | |||
+ | |||
+ | |||
+ | Система RTTI в С++. | ||
+ | |||
+ | Если в классе не определено ни одной виртуальной функции, то аналогии is и as ввести нельзя. Аналогии операций is и as. | ||
+ | |||
+ | 1. Операция dynamic_cast | ||
+ | dynamic_cast - это полный аналог as. | ||
+ | dynamic_cast<Student*>(pperson) == 0 - аналог is. | ||
+ | |||
+ | ==Лекция 14 (09.12.08)== | ||
+ | |||
+ | 2. Операция typeid и структура type_info | ||
+ | Посмотрим на поля и методы type_info. Попробуем повыводить на консоль typeid(выражение) и typeid(тип). | ||
+ | |||
+ | Задача (С++) о раскраске всех треугольников из vector<Shape*> - потомков класса Shape: | ||
+ | 1-ый способ: Покрасить все треугольники и их наследников. | ||
+ | 2-ой способ: Покрасить все треугольники, но не производные классы. | ||
+ | 3-ий способ: Покрасить все треугольники, но не производные классы, используя только полиморфизм. | ||
+ | |||
+ | Таблица виртуальных методов - внутренний механизм реализации полиморфизма (PABC.NET, Java и C++) | ||
+ | Рассмотрели иерархию классов (A ◅— B ◅— C) с не виртуальными и виртуальными методами и с разрывом цепочки виртуальности. Объявили переменную p: | ||
+ | var p: A; | ||
+ | инициализировали: | ||
+ | p := new A; | ||
+ | Затем последовательно присвоили p ссылки на B и на C и смотрели что происходит в памяти после каждого оператора присваивания. | ||
+ | Введены понятия VMT и vptr. Накладные расходы на вызов виртуальных методов (по памяти и по времени). | ||
+ | |||
+ | Интерфейсы (.NET и Java) | ||
+ | Определение интерфейса. Описание основных интрефейсов. Пример объявления класса, поддерживающего некоторые интрефейсы. |
Версия 19:34, 12 декабря 2008
Содержание
Лекция 1
Основы Java. Понятие виртуальной машины, схема компиляции и выполнения. Преимущества и недостатки виртуальной машины.
Первая программа на Java.
Переменные и константы. Стандартные типы. Правила приведения числовых типов.
Ввод-вывод. Класс Scanner.
Операторы.
Перечислимый тип.
Класс String, некоторые его методы.
Массивы. Оператор for(x: a). Класс java.util.Arrays.
Двумерные массивы.
Функции. Параметры. Отсутствие ссылочных параметров.
Лекция 2
АТД. Интерфейс, реализация, принцип сокрытия реализации.
Реализация АТД в виде класса.
Класс как модуль и как тип данных.
Инкапсуляция как объединение методов и полей в одной "капсуле".
Защита доступа в классе (private, public).
Синтаксис классов в PABC.NET и в Java. Вызов конструкторов.
Определение методов внутри и вне интерфейса класса (PascalABC.NET). Достоинства и недостатки каждого способа.
Класс Стек и его реализация на основе массива (PascalABC.NET, Java). Клиентская программа для класса Стек (PascalABC.NET, Java).
Вывод: семантика классов в PascalABC.NET и Java практически идентична, различается только синтаксис.
Хранение объектов классов в памяти. Ссылочная объектная модель. Присваивание и сравнение объектов. Нулевое значение объектной переменной.
Передача параметров по ссылке в Java - необходимость создания класса-обертки.
Лекция 3 (16.09.08)
Размерная модель классов в C++. Хранение объектов классов в памяти. Присваивание объектов.
Определение методов внутри и вне интерфейса класса (C++).
Где следует размещать код интерфейса класса и код реализации его методов.
Методы в записях PascalABC.NET. Размерная модель данных для записей.
Объекты C++ в динамической памяти. Необходимость явного освобождения памяти.
Лекция 4 (23.09.08)
Статические методы и поля в PascalABC.NET, Java и C++.
Статические конструкторы в PascalABC.NET, Java. Класс Динамический массив (PascalABC.NET).
Свойства. Свойства с индексами.
Стандартный класс двусвязного списка в библиотеке .NET.
Понятие итератора. Защита доступа. Интерфейс итератора. Итерация по списку с помощью итератора. Итерация с помощью foreach. Класс Множество на PascalABC.NET. Реализация с помощью списков и с помощью бинарных деревьев поиска.
Идея ускорения доступа. Хеширование. Хеш-таблица, хеш-функция.
Лекция 5 (30.09.08)
Реализация множества на основе хеш-таблицы.
Класс Ассоциативный массив на PascalABC.NET на основе списка.
Классы ассоциативных массивов в стандартной библиотеке NET. Итератор ассоциативного массива. Цикл foreach по ассоциативному массиву.
Контейнерные классы в Java: обзор. Классы-обертки (Integer, Double).
Стандартный класс двусвязного списка в библиотеке Java. Итератор списка. Итерация по списку.
Пакеты в Java. Пример использования пакетов.
Лекция 6 (07.10.08)
Библиотеки в PascalABC.NET. Многоязыковость. Отличие библиотек от модулей.
Библиотеки JAR в Java.
Перегрузка операций в C++ - общие правила.
Класс Date. Перегрузка операций +, +=, ++ (префиксной и постфиксной), ==, !=.
Дружественные функции в C++.
Лекция 7 (14.10.08)
Перегрузка операций << и >>
С++: выделение динамической памяти в конструкторе (на примере класса myvector).
Перегрузка операции [].
Деструкторы. Момент вызова деструктора.
Динамический массив в динамической памяти. Момент вызова конструктора и деструктора.
Моделирование ссылочной модели данных средствами C++.
Конструктор копии. КК, генерируемый по умолчанию. Когда его не достаточно.
Операция присваивания. Операция присваивания, генерируемая по умолчанию.
Ситуации, в которых вызывается конструктор копии.
Лекция 8 (21.10.08)
Шаблон класса myvector<T>. Особенности компиляции шаблонов. Где надо размещать описания шаблонов и почему.
Описание функции-члена вне интерфейса класса.
Понятие инстанцирования шаблона класса. Два уровня ошибок компиляции шаблонов: при компиляции собственно шаблона и в момент инстанцирования шаблона.
Массив объектов класса и роль конструктора по умолчанию.
Операция (). Примеры: реализация класса matrix и объекты-функции. Преимущества объектов-функций.
Лекция 9 (28.10.08)
Класс frac. Конструктор преобразования и операция приведения типа.
Ключевое слово explicit и запрет неявного преобразования.
Перегрузка операций в PascalABC.NET (на примере класса Frac). Агрегация класов и подобъекты (C++).
Вызов конструктора подобъекта.
Роль конструктора по умолчанию.
Порядок вызова конструкторов и деструкторов.
Клонирование и присваивание объектов в языках со ссылочной моделью хранения объектов (на примере PascalABC.NET)
Лекция 10 (11.11.08)
Наследование. Основные определения: базовый класс-производный класс, предок-потомок, надкласс-подкласс. Цели наследования. Описание на PABC.NET классов Student и SeniorSudent (наследник Student).
Наследование - это расширение или сужение? Наследование - это расширение интерфейса класса, но сужение количества представителей.
Переопределение и замещающие функции (PABC.NET). Ключевое слово inherited.
Вызов конструктора предка в конструкторе потомка (PABC.NET). Конструктор для SeniorSudent. Рекомендуется вызывать конструкторы предков первыми в конструкторе потомка, т.к. объект предка д.б. создан перед какими-то следующими действиями. В большинстве языков программирования конструкторы предка вызываются первыми принудительно. В качестве примера написали классы Queue<T> и CountingQueue<T> (наследник Queue с одним дополнительным полем - количеством элементов).
Принцип "Открыт-закрыт". "Код должен быть закрыт от изменения своего текста, но открыт для модификации своего поведения." Причины закрытия и открытия кода.
Наследование и включение. Понятие включения (физического и логического). Изображение отношений наследования и включения на UML-диаграммах.
Что выбрать — наследование или включение? Напишем классы Queue<T> и CountingQueue<T> с использованием включения (PABC.NET). Понятие делегирования. Достоинства наследования. Пример плохого использования наследования:
Код:
Circle = class( Point );
В обоих классах есть реализация конструктора и процедуры Draw.
Примеры с неоднозначным выбором наследования или включения.
Лекция 11 (18.11.08)
Наследование и выявление общего предка. Даны UML-нотации классов Student и Teacher. Заметим, что у них есть общие поля и методы. Решаем вынести их в базовый класс Person. Реализовали класс Teacher на Java, в т. ч. конструктор c super(...).
Вид доступа protected. Что значит protected. protected нарушает инкапсуляцию. Пример наследования Square от Rectangle на PABC.NET. Приходим к выводу, что иногда необходимо обращаться к полям и в этом случае следует использовать protected.
Класс Object — предок всех классов. Дан интерфейс класса Object в Java и .NET (не полный - из 4 и 3 методов соответственно).
Присваивание в иерархии Предок–потомок. Описаны переменные s (Student) и p (Person). Пытаемся одному присвоить другое. Делаем вывод, что переменная производного класса может быть неявно преобразована к типу базового класса, но не наоборот. Рассматриваем случай явного приведения типов. Вводятся понятия UpCast и DownCast.
Операции is и as (PABC.NET) и instanceof (Java). Определения статического и динамического типа переменной.
Два варианта использования операций is и as. 1.
Код:
if p is Student then // не точное совпадение типов, а то, является ли p разновидностью Student
Student(p).ChangeCourse(4);
Код:
if( p instanceof Student )
((Student)p).changeCourse(4);
2.
Код:
var s: Student := p as Student;
Код:
Student st = (Student) p;
Аналог операции is (instanceof), обеспечивающий точное соответствие типов.
На PABC.NET и Java.
Лекция 12 (25.11.08)
Наследование в С++. Вспомним наш излюбленный пример наследования на примере классов Person и Student. В предположении, что класс Person уже описан, опишем на С++ класс Student. Одно из полей Student типа char*. Понятие публичного наследования. Особенности вызова конструктора (деструктора) предка в конструкторе (деструкторе) потомка. Пример использования char* надуман! Не пытайтесь повторить это дома!
Совместимость по присваиванию и преобразование типов в иерархии Предок–Потомок. Описали переменные p (Person) и s (Student). Они хранятся на стеке (размерная модель). Пытаемся присвоить одному другое. Делаем вывод об отбрасывании дополнительных полей производного класса при присваивании.
Совместимость по присваиванию для типов указателей и ссылок. Присвоение указателям (ссылкам): UpCast - неявно, DownCast - только явно (с помощью операции static_cast).
Конструктор копии и оператор присваивания для класса Student.
Полиморфизм и виртуальные функции. (Java) Пусть в классах Person и Student есть метод print().
Замещение (переопределение) методов.
Код:
Person p = new Student(...); p.print();
Метод print() какого класса будет вызван? В Java - класса Student, а в OP и C++ (по умолчанию) - класса Person. Понятия раннего и позднего связывания.
Реализация позднего связывания на OP. Виртуальные методы. Модификатор virtual и ключевое слово override. Определение полиморфизма.
Реализация полиморфизма в С++. Аналогично в классах Person и Student описан метод print(). Присвоим объекту класса Person объект класса Student и вызовем для него метод print(). Вызовется print() класса Person. Сделаем метод виртуальным (virtual в заголовке). Все равно будет вызван метод класса Person. Причина: при присваивании происходит отбрасывание дополнительных полей и потеря информации о типе. Выход: полиморфизм в С++ работает только через указатели или ссылки на базовый класс.
В Java все методы (за исключением статических) виртуальные.
Лекция 13 (02.12.08)
Виртуальные функции как блоки для замены кода. 1. При разработке базового класса надо думать о будущем коде. 2. Полиморфизм заставляет работать уже откомпилированный код совершенно по-другому. Определение полиморфного объекта (объекта, обладающего полиморфным поведением), полиморфной подпрогораммы.
Виртуальные методы в классе Object. В С++ нет класса, базового для всей иерархии классов. Рассмотрели пример переопределения метода ToStrintg класса Object на PABC.NET.
Цепочки виртуальности и ее разрыв. Определение цепочки виртуальности. Алгоритм поиска в цепочке виртуальности метода, который следует вызывать. Разрыв цепочки виртуальности. Идентификатор reintroduce (NET).
С++ - виртуальные деструкторы Конструкторы в С++ виртуальными быть не могут, а деструкторы могут. Правило: Если в классе есть хотя бы одна виртуальная функция или нет, но в подклассах они могут появиться, то деструктор этого класс следует сделать виртуальным. Правило: Если деструктор базового класса виртуальный, то сгенерированный деструктор также будет виртуальным.
Полиморфные контейнеры
Полиморфный контейнер в .NET Рассмотрели пример на PABC.NET в котором Shape - это предок классов геометрических фигур. Хотим написать методы Draw и Hide. Вместо этого (вместе с этим) дали определение абстрактного метода и абстрактного класса. Идем дальше. Реализовали класс Shape. В глаза бросается метод MoveTo, который вызывает два абстрактных виртуальных метода (Hide и Draw). Интересно, он вообще работает... Ответ: да, работает, ведь перед Hide и Draw неявно стоит self - ссылка, - как раз то, что надо для виртуальных методов. Заполнили List<Shape> объектами производного от Shape класса, в одном цикле foreach нарисовали их, в другом переместили. Определение полиморфного контейнера. Если класс абстрактный, то объекты этого класса создавать нельзя.
Полиморфный контейнер на С++. Написали тот же класс Shape на С++. Здесь Hide и Draw называются уже чисто виртуальными ( =0 ). Затем заполнили vector<Shape*> объектами производного класса, в цикле (с итератором) нарисовали их, а потом еще и переметили на заданный ветктор. Полиморфное клонирование в полиморфном контейнере.
Система RTTI в С++.
Если в классе не определено ни одной виртуальной функции, то аналогии is и as ввести нельзя. Аналогии операций is и as.
1. Операция dynamic_cast dynamic_cast - это полный аналог as. dynamic_cast<Student*>(pperson) == 0 - аналог is.
Лекция 14 (09.12.08)
2. Операция typeid и структура type_info Посмотрим на поля и методы type_info. Попробуем повыводить на консоль typeid(выражение) и typeid(тип).
Задача (С++) о раскраске всех треугольников из vector<Shape*> - потомков класса Shape: 1-ый способ: Покрасить все треугольники и их наследников. 2-ой способ: Покрасить все треугольники, но не производные классы. 3-ий способ: Покрасить все треугольники, но не производные классы, используя только полиморфизм.
Таблица виртуальных методов - внутренний механизм реализации полиморфизма (PABC.NET, Java и C++) Рассмотрели иерархию классов (A ◅— B ◅— C) с не виртуальными и виртуальными методами и с разрывом цепочки виртуальности. Объявили переменную p: var p: A; инициализировали: p := new A; Затем последовательно присвоили p ссылки на B и на C и смотрели что происходит в памяти после каждого оператора присваивания. Введены понятия VMT и vptr. Накладные расходы на вызов виртуальных методов (по памяти и по времени).
Интерфейсы (.NET и Java) Определение интерфейса. Описание основных интрефейсов. Пример объявления класса, поддерживающего некоторые интрефейсы.