
- •В.В. Чуркин технологии программирования
- •Содержание
- •Введение
- •Указатели. Операции над указателями Операции адресации и разыменования.
- •Арифметические операции.
- •Присваивание указателей.
- •Смещение и индексирование указателей.
- •Функции
- •Объявление функции (прототип)
- •Параметры функции
- •Встроенные функции
- •Функции с параметрами со значениями по умолчанию
- •Параметры функции main()
- •Рекурсивные функции
- •Перегрузка функций
- •Шаблоны функций
- •Указатели на функции
- •Объявление и инициализация массива указателей на функции:
- •Указатель на функцию как возвращаемое функцией значение
- •Выделение и освобождение динамической памяти
- •Символьные и строковые данные Символьные константы
- •Строковые константы (строки)
- •Символьные переменные
- •Строки – переменные
- •Специальные функции ввода-вывода строк
- •Стандартная библиотека функций языка с
- •Файлы Потоковый ввод-вывод в языке с Функции верхнего уровня файлового ввода-вывода
- •Открытие и закрытие потока
- •Текстовый режим
- •Бинарный режим
- •Закрытие файла
- •Функции в языке c для работы с файлами
- •Двоичный (бинарный) режим обмена с файлами
- •Строковый обмен с файлами
- •Форматный обмен с файлами
- •Позиционирование в потоке
- •Ввод-вывод нижнего уровня
- •Открытие / закрытие файла
- •Чтение и запись данных
- •Произвольный доступ к файлу
- •Позиционирование файлов
- •Сортировки числовых массивов Принцип наименьших привилегий
- •Обменная сортировка (SwapSort)
- •Сортировка выбором (SelectSort)
- •Пузырьковая сортировка (BubbleSort)
- •Сортировка вставками (InsertSort)
- •Быстрая сортировка (QuickSort)
- •Поиск в числовых массивах
- •Структуры
- •Форматы определения структурных типов
- •Форматы определения объектов структурных типов
- •Операции над объектами структурного типа
- •Доступ к элементам объектов структурного типа
- •Структуры, массивы и указатели
- •Объединения (смеси)
- •Оператор switch (переключатель)
- •Динамические структуры данных
- •Реализация стека с помощью массива
- •Очередь
- •Очередь приоритетов
- •Реализация очереди с помощью массива
- •Линейные списки
- •Функции для работы с двунаправленным линейным списком
- •Реализация списка с помощью массивов
- •Поиск хэшированием
- •Бинарные деревья
- •Бинарное упорядоченное дерево (дерево поиска)
- •Идеально сбалансированное дерево
- •Операции с бинарным упорядоченным деревом
- •Удаление узла из дерева
- •Обход (просмотр) дерева
- •Реализация дерева с помощью массивов
- •Вывод динамических структур в файл и чтение их из файла
- •Сбалансированные (avl) деревья
- •Алгоритм avl-вставки.
- •Повороты
- •Классы и объектно-ориентированное программирование
- •Объявление класса
- •Определение класса (реализация класса)
- •Использование класса (драйвер класса)
- •Доступ к элементам класса
- •Отделение интерфейса от реализации
- •Обслуживающие функции-утилиты
- •Конструкторы
- •Windows-программы в Builder
- •Структура головного файла проекта
- •Структура заголовочного файла модуля формы (“Unit1.H”)
- •Структура файла реализации модуля формы (“Unit1.Cpp”)
- •Области видимости (или области действия) переменных в блоках. Время жизни переменных
- •Доступ к свойствам и функциям-элементам (методам) объектов, переменным и функциям в приложении, содержащем одну форму
- •Константные объекты и константные функции-элементы
- •Перегрузка операций
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Перегрузка операции индексирования []
- •Композиция классов
- •Дружественные функции класса
- •Дружественный класс
- •Использование указателя this
- •Статические элементы класса
- •Шаблон класса для статически и динамически создаваемых объектов
- •Конструктор 1
- •Деструктор
- •Вызовы конструкторов и деструкторов
- •Перегруженная операция присваивания
- •Конструктор 2 (конструктор копирования, конструктор копии)
- •Наследование. Иерархия классов.
- •Ключи доступа
- •Пример простого наследования (точка, круг)
- •Правила наследования функций-элементов. Вызовы конструкторов и деструкторов в иерархии
- •Виртуальные функции и полиморфизм
- •Правила определения и наследования виртуальных функций
- •Позднее (динамическое) связывание
- •Полиморфизм. Абстрактные и конкретные классы
- •Учебная литература (основная)
- •Учебная литература (для углубленного изучения)
- •Учебно-методические издания
Правила определения и наследования виртуальных функций
1) Если в базовом классе функция-элемент определена как виртуальная, то функция-элемент, определенная в производном классе с тем же именем и тем же набором параметров, автоматически становится виртуальной, а с отличающимся набором параметров – обычной.
2) Виртуальные функции наследуются, поэтому переопределять их нужно только при отличиях. Права доступа при переопределении изменить нельзя.
3) Если виртуальная функция-элемент переопределена в производном классе, объекты этого класса могут получить доступ к функции-элементу базового класса с помощью операции (::).
4) Виртуальные функции не могут быть static, но могу быть friend.
5) В базовом классе виртуальная функция может быть определена как чистая виртуальная:
virtual ……()=0;
6) Чистая виртуальная функция должна переопределяться в производном классе (возможно, опять как чистая виртуальная).
Если в классе point функцию-элемент определить как виртуальную
virtual float getx() const;
решение о том, функция-элемент какого класса будет вызвана, будет приниматься в зависимости от типа объекта, на который ссылается указатель.
point *p, *c;
p=new point; //создается объект класса point
c=new circle; // создается объект класса circle
p->getx(); //вызывается функция—элемент point::get()
c->getx(); // вызывается функция—элемент circle::get()
Для обхода механизма виртуальных функций нужно:
c->point::getx();
Примечания.
1) Виртуальной называется функция, ссылка на которую разрешается на этапе выполнения программы.
2) Виртуальный механизм работает только при использовании указателей или ссылок на объекты.
3) Деструкторы рекомендуется делать виртуальными для того, чтобы правильно освобождать память из-под динамического объекта (операцией delete), поскольку в этом случае в любой момент времени будет выбран деструктор, соответствующий фактическому типу объекта.
Позднее (динамическое) связывание
Для каждого класса, содержащего хотя бы одну виртуальную функцию-элемент, компилятор создает таблицу виртуальных функций (vtbl), в которой для каждой виртуальной функции записан её адрес в памяти. Адреса виртуальных функций содержатся в таблице в порядке их описания в классах. Адрес любой виртуальной функции имеет в vtbl одно и то же смещение для каждого класса в пределах иерархии.
Каждый объект содержит скрытое дополнительное поле ссылки на vtbl, называемое vptr. Поле vptr заполняется конструктром при создании объекта. Для этого компилятор добавляет в начало тела конструктора соответствующие инструкции.
На этапе компиляции ссылки на виртуальные функции заменяются на обращение к vtbl через vptr объекта, а на этапе выполнения в момент обращения к виртуальной функции её адрес выбирается из таблицы.
Таким образом, вызов виртуальной функции, в отличие от вызовов других функций-элементов, выполняется через дополнительный этап получения адреса виртуальной функции-элемента из таблицы. Это замедляет выполнение программы.
Полиморфизм. Абстрактные и конкретные классы
Объект, определенный через указатель или ссылку и содержащий виртуальные функции, является полиморфным. Полиморфизм состоит в том, что с помощью одного и того же обращения к функции-элементу выполняются различные действия в зависимости от типа объекта, на который ссылается указатель в каждый момент времени.
Абстрактным является класс, который не может порождать объекты. Он содержит хотя бы одну чистую виртуальную функцию. Можно объявлять указатели и ссылки на абстрактный класс, если при инициализации не требуется создавать временный объект. Конкретный класс может порождать объекты; в нем определены все функции-элементы.
Можно создать функцию-элемент, параметром которой является указатель на абстрактный класс. На место этого параметра при выполнении программы может передаваться указатель на объект любого производного класса. Так создаются полиморфные функции, работающие с объектом любого типа в пределах иерархии.