3.11M
Category: programmingprogramming

Объектно-ориентированное программирование на C++

1.

Объектно-ориентированное
программирование на C++

2.

Причины возникновения
объектно-ориентированного
программирования

3.

С ростом объема кода программы
становится невозможным
удерживать в памяти все детали

4.

Необходимо структурировать
информацию, выделять главное
и отбрасывать несущественное

5.

Этот процесс называется
повышением степени
абстракции программы

6.

Одним из естественных
вариантов борьбы со сложностью
является алгоритмическая
декомпозиция -разбиение
задачи на подзадачи

7.

Процедурное
программирование –
подход, при котором исходная
задача разбивается на подзадачи

8.

Каждая подзадача
оформляется в виде функции

9.

Использование функций - первый
шаг к повышению абстракции

10.

Это позволяет отвлечься от
деталей ее реализации, поскольку
для вызова функции требуется
знать только ее интерфейс

11.

Следующий шаг — описание
собственных типов данных,
позволяющих структурировать и
группировать информацию

12.

Процедурное программирование –
подход, при котором функции и
переменные, относящиеся к
какому-то конкретному объекту
свободно располагаются в коде и
никак между собой не связаны

13.

Следующий шаг к повышению
абстракции – объектноориентированный подход

14.

Объектная декомпозиция –
выделение сущностей из
предметной области

15.

Каждая сущность
представляется в коде
программы в виде класса

16.

Класс - общее абстрактное
описание некоторой сущности

17.

Объектно-ориентированное
программирование –
подход, при котором объекты
реального мира представляются в
коде в виде экземпляров классов

18.

Программа представляет собой
совокупность
взаимодействующих объектов,
имеющих состояние и поведение

19.

Интернет-магазин бытовой техники

20.

Объектно-ориентированное
программирование –
подход, при котором функции и
переменные, относящиеся к
конкретному объекту объединены в
коде и тесно связаны между собой

21.

Концепция «черного ящика»
является одной из базовых
концепций ООП

22.

Снаружи объект принято
рассматривать как «черный ящик»,
т.е. некий прибор с кнопками

23.

Основные понятия ООП
• Инкапсуляция
• Наследование
• Полиморфизм

24.

Инкапсуляция –
это объединение полей и методов
объекта в единое целое - класс

25.

Синтаксис объявления класса
class имя_класса
{
[private | protected | public]:
тип_поля1 имя_поля1;
тип_поля2 имя_поля2;
тип_поля3 имя_поля3;
...
тип1 имя_метода1(список_параметров)
{
...
}
тип2 имя_метода2(список_параметров)
{
...
}
...
} [список_переменных];

26.

Способы доступа к
компонентам класса
• Открытый (public)
• Защищенный (protected)
• Закрытый (private)

27.

Пример объявления класса

28.

Важнейшее требование
инкапсуляции - скрытие состояния
объекта от внешнего мира

29.

Инкапсуляция повышает
степень абстракции программы

30.

Данные класса и реализация
методов класса находятся ниже
уровня абстракции, и для
написания программы
информация о них не требуется

31.

Инкапсуляция позволяет изменить
реализацию класса без модификации
основной части программы, если
интерфейс остался прежним

32.

Наследование –
это механизм, который позволяет
расширять существующие классы,
сохраняя их функциональность и
добавляя им новые свойства и методы

33.

Полиморфизм –
это механизм, который позволяет
использовать одно и тоже имя для
решения нескольких технически
разных задач

34.

Объект как экземпляр класса –
это некоторая уникальная единица,
имеющая свои переменные (поля)
и функции (методы), эти
переменные обрабатывающие

35.

Поля объекта - это переменные,
описывающие его состояние, а
методы - это способ перевести
объект из одного состояния в другое

36.

Пример создания объекта
класса

37.

Методы-аксессоры
• Инспекторы позволяют
получить значения полей
• Модификаторы позволяют
установить значения полей

38.

Методы-аксессоры

39.

Конструктор это специальный метод класса,
который вызывается для
конструирования объекта в
момент его создания

40.

Конструктор не возвращает
значение, даже типа void

41.

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

42.

Конструктор, вызываемый без
параметров, называется
конструктором по умолчанию

43.

Параметры конструктора
могут иметь любой тип,
кроме этого же класса

44.

Если программист не указал ни
одного конструктора, компилятор
создаст его автоматически

45.

Деструктор –
это специальный метод класса,
который вызывается при
уничтожении объекта

46.

Деструктор не принимает
никаких параметров и не
возвращает значений

47.

Класс может иметь только один
деструктор

48.

Если деструктор явным образом
не определен, компилятор
автоматически создаст пустой
деструктор

49.

this – константный указатель на
объект класса, который неявно
передается в каждый
нестатический метод класса

50.

Конструктор копирования

51.

Три ситуации, когда новый
объект конструируется путем
копирования существующего
• Объект создается и инициализируется
другим объектом
• Объект передается в функцию по
значению
• Объект возвращается из функции по
значению

52.

Объект создается и инициализируется
другим объектом

53.

Объект передается в функцию
по значению

54.

Объект возвращается из функции
по значению

55.

Если в объекте класса есть
указатель, адресующий участок
динамической памяти, то создается
предпосылка возникновения ошибки
на этапе выполнения программы

56.

Объект создается и инициализируется
другим объектом

57.

Объект передается в функцию
по значению

58.

Объект возвращается из функции
по значению

59.

При поэлементном копировании
указатели двух различных объектов
будут адресовать один и тот же
участок динамической памяти

60.

При разрушении одного из объектов
сработает деструктор, который
освободит динамическую память

61.

При разрушении второго объекта
снова сработает деструктор,
который попытается повторно
удалить ранее освобожденный
участок динамической памяти

62.

Произойдет ошибка этапа
выполнения программы

63.

Для решения данной проблемы
необходимо обеспечить класс
собственной реализацией
конструктора копирования

64.

В конструкторе копирования
необходимо выделить память
для указателя вновь
создаваемого объекта

65.

Конструктор копирования

66.

Статические элементы класса

67.

Статические поля класса – это
глобальные переменные,
доступные только в пределах
области класса

68.

Статические поля применяются
для хранения данных, общих для
всех объектов класса

69.

Эти поля существуют для всех
объектов класса в единственном
экземпляре, то есть не
дублируются

70.

Статические поля класса должны
быть определены глобально
после описания класса

71.

В этом случае под них будет
выделено соответствующее
количество байт памяти

72.

Статические поля класса

73.

Статические поля доступны
как через имя класса, так и
через имя объекта

74.

На статические поля
распространяется действие
спецификаторов доступа

75.

Память, занимаемая статическим
полем, не учитывается при
определении размера объекта с
помощью операции sizeof

76.

Статические методы
предназначены для обращения к
статическим полям класса

77.

Статическим методам не
передается скрытый указатель
на объект класса (this)

78.

Поэтому они могут обращаться
непосредственно только к
статическим полям и вызывать
только статические методы класса

79.

Статические элементы класса

80.

Обращение к статическим
методам производится либо
через имя класса, либо через
имя объекта

81.

Перегрузка операторов

82.

Перегрузка операторов –
возможность интегрировать
пользовательский тип данных в
язык программирования

83.

Перегрузка операторов дает
возможность определить
собственные действия для
стандартных операций, применяемых
к объектам пользовательского типа

84.

Общий синтаксис перегрузки
операторов
тип operator знак_операции (параметры)
{
< тело функции >
}

85.

Ограничения
• Нельзя перегружать операции для
стандартных типов
• Нельзя создавать новые названия
операций
• Перегрузка не меняет приоритет
операций
• В С++ нет неявной перегрузки операций
• Для той или иной операции нельзя
изменить количество операндов

86.

Запрещенные к перегрузке
операторы
• :: - оператор разрешения области
видимости
• sizeof - оператор определения
размера объекта
• . - оператор выбора
• ?: - условный тернарный оператор

87.

Способы перегрузки
операторов
• Функция-операция представляется в
виде метода класса
• Функция-операция представляется в
виде обычной или дружественной
функции

88.

Дружественные функции

89.

Функция, объявленная в классе
с ключевым словом friend,
является дружественной по
отношению к данному классу

90.

Это означает, что данная
функция имеет прямой доступ
к скрытым полям класса

91.

Поскольку дружественной
функции не передается указатель
this, то она должна принимать в
качестве параметра ссылку на
объект класса

92.

Дружественные функции

93.

На дружественные функции
не распространяются
спецификаторы доступа

94.

Одна функция может быть
дружественной сразу
нескольким классам

95.

Другом может быть не только
функция, но и метод другого
ранее определенного класса

96.

Дружественные методы

97.

Если все методы какого-либо
класса должны иметь доступ к
скрытым полям другого, то весь
класс объявляется дружественным

98.

Дружественный класс

99.

Важно понимать, что класс сам
определяет, какие функции и
классы являются
дружественными, а какие нет

100.

Шаблоны функций

101.

Шаблоны используются, когда
необходимо создать функции,
которые применяют один и тот же
алгоритм к различным типам данных

102.

Шаблон функции – это
обобщенное описание функции

103.

У такой функции хотя бы один
формальный параметр имеет
обобщенный тип

104.

Определение шаблона
функции

105.

Использование шаблона функции

106.

В момент вызова функции
компилятор автоматически
создает специализированную
версию функции, где вместо
параметра типа подставляется
конкретный тип данных

107.

Этот процесс называется
инстанцированием шаблона или
созданием экземпляра шаблона

108.

Повторный вызов функции с
теми же типами параметров не
спровоцирует генерацию
дополнительной копии функции,
а вызовет уже существующую

109.

Использование шаблона функции

110.

Определение шаблона функции
не вызывает самостоятельную
генерацию кода компилятором

111.

По этой причине реализацию
шаблонов функций следует
размещать в заголовочном файле

112.

Компилятор создает код функции
только в момент ее вызова, и
генерирует при этом
соответствующую версию функции

113.

Каждый параметр типа, который
встречается в угловых скобках,
должен обязательно появиться в
списке параметров функции

114.

В противном случае произойдет
ошибка этапа компиляции

115.

Определение шаблона
функции

116.

Перегруженные шаблоны

117.

Явная специализация шаблона

118.

Специализация переопределяет
шаблон, а обычная нешаблонная
функция переопределяет и
специализацию, и шаблон

119.

120.

Важно понимать, что
использование шаблонов функций
не приводит к уменьшению
результирующего объектного кода

121.

Однако экономит время
разработки программы

122.

Динамические структуры данных

123.

При решении большинства
реальных современных задач для
хранения данных приходится
использовать динамическую память

124.

До сих пор мы пользовались
обычными динамическими
массивами

125.

При добавлении и удалении
элементов массива приходилось
перераспределять память

126.

Динамический массив предполагает
такой способ хранения информации,
при котором можно получить
произвольный доступ к любому
элементу массива по индексу

127.

Произвольный доступ к элементам
является специфической
особенностью массива как
динамической структуры данных

128.

Такой способ хранения
информации является наиболее
часто используемым, но не
единственным

129.

Динамическая структура данных –
структура данных определенного
формата с определенным способом
доступа к ее элементам и
автоматическим расширением
размера при необходимости

130.

Каждая динамическая структура
данных имеет определенный
набор операций с ее элементами

131.

Наиболее часто
используемые динамические
структуры данных
Стек
Очередь
Связный список
Бинарное дерево

132.

Стек - это динамическая
структура данных, которая
функционирует по принципу LIFO
(Last In First Out)

133.

Работа стека организована таким
образом, что элементы добавляются
и удаляются с одного конца,
называемого вершиной стека

134.

Кроме того, стек обладает
базовым адресом - начальным
адресом, по которому стек
размещается в памяти

135.

Динамическая структура данных
«Стек»

136.

Основные операции над
стеком и его элементами
• Добавление элемента в стек
• Удаление элемента из стека
• Просмотр элемента в вершине
стека без удаления
• Очистка стека

137.

Добавление элемента в стек

138.

Удаление элемента из стека

139.

Просмотр элемента в вершине
стека без удаления

140.

Очистка стека

141.

Важно понимать, что стек не
определяет новый способ
хранения данных в памяти, а
предоставляет новый способ
доступа к данным

142.

Стек широко используются в
системном программном
обеспечении, включая
компиляторы и интерпретаторы

143.

Очередь - это динамическая
структура данных, которая
функционирует по принципу FIFO
(First In First Out)

144.

Очередь чаще всего используется
в задачах моделирования
различных систем обслуживания

145.

Разновидности очереди
• Классическая очередь
• Кольцевая очередь
• Очередь с приоритетом

146.

Классическая очередь

147.

Кольцевая очередь

148.

Очередь с приоритетом

149.

Очередь с приоритетом

150.

Важно понимать, что очередь не
определяет новый способ
хранения данных в памяти, а
предоставляет новый способ
доступа к данным

151.

Односвязный список

152.

Основной способ хранения
информации, который
используется в программах это массивы

153.

При использовании массивов
наиболее эффективно
выполняются операции доступа к
элементам (чтение/изменение)

154.

В то время как операции
вставки/удаления будут
значительно менее эффективны

155.

В задачах, где операции
вставки/удаления используются
намного чаще, чем операции
чтения/изменения, использование
массивов оказывается
неэффективным

156.

Для решения этой проблемы
используются такие
динамические структуры данных
как связные списки

157.

Односвязный список — это набор
элементов, связанных между
собой с помощью указателя-связки

158.

Односвязный список

159.

Принципиальное отличие
списка от массива заключается
в том, что элементы списка
хранятся не одним блоком в
памяти, а каждый отдельно

160.

Список вынужден хранить не
только сами данные, но
дополнительную служебную
информацию

161.

Такой служебной информацией
в списке является указатель на
следующий элемент (next)

162.

Этот указатель связывает
хранящиеся отдельно в памяти
элементы списка в единую
динамическую структуру

163.

Связь между элементами списка
однонаправленная, поэтому
список называется односвязным

164.

В качестве точки входа в список
используется указатель на его
первый элемент, называемый
головой списка (head)

165.

Вставка узла в определенное
место списка

166.

Удаление узла из списка

167.

Именно благодаря такой структуре
списка, в нем весьма эффективно
осуществляются операции
вставки/удаления элементов

168.

Однако, скорость доступа к
элементам у списка ниже, чем
у массива

169.

Двусвязный список

170.

Недостаток односвязного списка –
однонаправленная связь между
его элементами

171.

Из первого элемента списка
попасть во второй можно, а
обратно уже нет

172.

Вместо этого придется заново
перебирать все элементы, начиная
с головы списка, что приводит к
потере производительности

173.

Для решения этой проблемы
следует добавить в каждый
элемент списка еще одно
служебное поле

174.

В этом поле будет храниться
указатель на предыдущий
элемент (previous)

175.

Тогда из любого элемента списка
можно будет попасть не только в
следующий за ним элемент в
списке, но и в предыдущий

176.

Двусвязный список

177.

Такая структура предоставляет
возможность двунаправленно
перебирать список

178.

Первый элемент двусвязного
списка называется головой
списка (head)

179.

Последний элемент двусвязного
списка называется хвостом
списка (tail)

180.

Вставка узла в определенное
место двусвязного списка

181.

Удаление узла из двусвязного
списка

182.

Бинарные деревья поиска

183.

Бинарное дерево – это
структурированная совокупность
узлов, каждый из которых может
иметь одного предка и двух
потомков

184.

Под предком понимают
родительский узел, а потомком
называют дочерний узел

185.

Бинарное дерево – это
динамическая структура данных,
в которой элементы изначально
упорядочены

186.

Каждый узел бинарного дерева
помимо данных имеет ключ,
который однозначно
идентифицирует узел

187.

Бинарное дерево поиска

188.

Для каждого узла бинарного
дерева в левой ветке содержатся
только те ключи, которые имеют
значения, меньшие, чем
значение данного узла

189.

Для каждого узла в правой ветке
содержатся ключи, имеющие
значения, большие (или равные),
чем значение данного узла

190.

Бинарное дерево эффективно
используется для поиска
информации

191.

Однако, в этом случае
бинарное дерево должно быть
сбалансированным – расти в
ширину, а не в высоту

192.

Если бинарное дерево не
сбалансировано, то поиск
данных будет достаточно долгим

193.

В отличие от массива бинарное
дерево хранит отсортированную
информацию не в линейном
виде, а в иерархическом

194.

Узел, который не имеет предка,
является корнем бинарного
дерева

195.

Узел, который не имеет
потомков, называется листом

196.

Бинарное дерево поиска

197.

Структура узла
бинарного дерева

198.

Добавление узла в
бинарное дерево

199.

При добавлении узел
вставляется в дерево таким
образом, что дерево не нужно
специально сортировать

200.

Узел сразу вставляется в
«правильную» позицию, причем
такая позиция единственная

201.

При удалении узла из дерева
возможны три ситуации

202.

Если удаляемый узел дерева
является листом, то удаление
такого узла является
тривиальной задачей

203.

Удаление узла из дерева

204.

Если удаляемый узел имеет только
одного потомка, тогда дочерний
узел напрямую соединяется с
родительским узлом

205.

Удаление узла из дерева

206.

Если удаляемый узел имеет двух
потомков, тогда отыскивается
следующий узел дерева и данные
из него копируются в удаляемый
узел, после чего следующий узел
удаляется из дерева

207.

Удаление узла из дерева

208.

Агрегация и композиция

209.

Агрегирование (агрегация) –
это включение объекта
(объектов) одного класса в
состав объекта другого класса

210.

Агрегация — отношение между
двумя равноправными объектами,
при котором один объект
(контейнер) имеет ссылку на
другой объект

211.

Оба объекта могут существовать
независимо: если контейнер
будет уничтожен, то его
содержимое — нет

212.

Пример отношения агрегации
Пе рсональный
компьюте р
Систе мный
блок
Монитор
Клавиатура
Мышь

213.

Пример отношения агрегации

214.

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

215.

Если контейнер будет уничтожен,
то и включённый объект тоже
будет уничтожен

216.

Пример отношения композиции
Окно программы
1
1
Заголовок
1
2
Полоса
прокрутки
1
1
1
Рабочая
область
1
Главное
ме ню

217.

Пример отношения композиции

218.

Пример отношения агрегации
и композиции

219.

Наследование

220.

Наследование – механизм языка
С++, который позволяет расширять
существующие классы, сохраняя
их функциональность и добавляя
им новые свойства и методы

221.

Класс, от которого наследуются
называют базовым классом

222.

Класс, который наследует
некоторый класс называют
классом-наследником или
производным классом

223.

Таким образом, наследование
позволяет повторно использовать
уже написанный код, расширяя и
дополняя его при необходимости
новыми функциональными
возможностями

224.

Общий синтаксис
наследования
class <имя производного класса>:
[спецификатор наследования]
<имя базового класса>
{
<элементы класса>
};
[спецификатор наследования] =
public | protected | private

225.

Спецификатор наследования
определяет каким будет в
производном классе доступ к
полям базового класса

226.

Если спецификатор наследования
не указан, то по умолчанию для
классов будет private, а для
структур - public

227.

Пример наследования

228.

Спецификаторы доступа

229.

Важно понимать, что все
унаследованные private-поля хотя
и недоступны непосредственно в
объектах производного класса, но
всё равно содержатся в них

230.

Конструкторы и деструкторы
не наследуются

231.

При создании объекта
производного класса
вызываются конструкторы всех
классов иерархии, начиная с
самого верхнего и заканчивая
конструктором этого
производного класса

232.

Деструкторы, соответственно,
вызываются в обратном порядке

233.

234.

235.

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

236.

237.

238.

239.

240.

241.

В конструкторе производного
класса следует явно
инициализировать только новые
поля, которые не были
унаследованы от базового класса

242.

При помощи списка
инициализаторов мы сообщаем
компилятору какой именно
конструктор следует вызвать

243.

Если необходимо изменить
функциональность производного
класса относительно базового
класса, то используется
переопределение методов

244.

Если в производном классе
имеется метод с таким же
именем и сигнатурой, как и в
базовом классе, такой метод
считается переопределённым

245.

246.

247.

248.

Если в производном классе
имеется метод с точно таким же
именем как и в базовом классе, но
различной сигнатурой, то такой
метод называется замещённым

249.

250.

251.

252.

Множественное наследование

253.

При множественном наследовании
производный класс наследуется от
нескольких базовых классов

254.

Пример множественного
наследования

255.

При множественном наследовании
порядок вызова конструкторов
базовых классов определяется не
списком инициализаторов, а
порядком, в котором указаны
базовые классы при объявлении
производного класса

256.

Порядок вызова конструкторов

257.

Деструкторы вызываются в
порядке, обратном порядку вызова
конструкторов

258.

Главной проблемой
множественного наследования
являются конфликты имен

259.

Конфликты имен

260.

Для решения этой проблемы
необходимо использовать
операцию разрешения контекста
для доступа к полям в
производном классе

261.

Решение проблемы конфликта
имен

262.

«Ромбовидное» наследование

263.

Проблема «ромбовидного»
наследования состоит в том, что в
производном классе D
дублируется поле из класса A

264.

Для решения проблемы
необходимо класс A сделать
виртуальным базовым классом
и обеспечить его конструктором
по умолчанию

265.

Решение проблемы
«ромбовидного» наследования

266.

При создании объекта производного
класса в цепочке вызовов
конструкторов сначала вызываются
конструкторы по умолчанию
виртуальных базовых классов, в
порядке следования слева направо,
а затем все остальные конструкторы

267.

Полиморфизм

268.

Механизм раннего связывания

269.

270.

Механизм раннего связывания

271.

Поскольку тип объектной
переменной известен на этапе
компиляции программы, то
связывание вызова метода с
самим кодом метода происходит
на этапе построения программы

272.

Такое связывание называется
ранним связыванием

273.

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

274.

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

275.

Это позволяет абстрагироваться
от конкретного объекта, от
конкретной реализации

276.

Это дает возможность выбирать
любую реализацию во время
выполнения программы

277.

Т.е. работать с любым объектом
через указатель на базовый класс

278.

279.

При работе с объектом
производного класса через
указатель на базовый класс
связывание вызова метода с
самим кодом метода происходит
на этапе построения программы

280.

В результате вызывается метод
класса, соответствующий типу
указателя, а не типу объекта,
который адресуется через
данный указатель

281.

Это, по-прежнему, раннее
связывание

282.

При работе с объектом
производного класса через
указатель на базовый класс
желательно, чтобы связывание
вызова метода с самим кодом
метода происходило на этапе
выполнения программы

283.

Необходимо, чтобы вызывался
метод в соответствии с типом
объекта, а не типом указателя,
который адресует данный объект

284.

Для решения данной проблемы
в базовом классе
переопределяемый метод
объявляется как виртуальный

285.

В производных классах этот
виртуальный метод
переопределяется

286.

Класс, который содержит хотя
бы один виртуальный метод,
называется полиморфным

287.

288.

289.

Для каждого класса иерархии, в
котором определяется или
переопределяется виртуальный
метод, компилятор создаёт
таблицу виртуальных функций

290.

В этой таблице содержатся
адреса всех виртуальных методов
в порядке их описания в классе

291.

Адрес любого виртуального
метода имеет в таблице одно и
то же смещение для каждого
класса в пределах иерархии

292.

Каждый объект полиморфного
класса содержит
дополнительное поле-указатель
vptr на таблицу виртуальных
функций

293.

Этот указатель vptr заполняется
конструктором при создании
объекта

294.

На этапе компиляции
программы все обращения к
виртуальным методам
заменяются на обращения к
таблице через vptr объекта

295.

На этапе выполнения в момент
обращения к виртуальному
методу его адрес выбирается из
таблицы и выполняется вызов

296.

В этом и заключается механизм
позднего связывания

297.

Механизм позднего
связывания

298.

Таким образом, вызов
виртуального метода, в отличие
от обычных методов, выполняется
через дополнительный этап
получения адреса метода из
таблицы виртуальных функций

299.

В производных классах
переопределённые виртуальные
методы не обязательно объявлять
с ключевым словом virtual

300.

Отсюда вытекает правило
виртуальности: метод,
объявленный виртуальным в
некотором классе, остается
виртуальным во всех его потомках

301.

Если в базовом классе
имеется виртуальный метод,
то в производном классе
метод с таким же именем и
сигнатурой автоматически
становится виртуальным

302.

Виртуальный метод не может
быть статическим, однако
может быть другом в
некотором классе

303.

Объект, который адресуется
через указатель или ссылку и
имеет хотя бы один виртуальный
метод, называется полиморфным

304.

Виртуальный метод, объявленный
в базовом классе, наследуется
производными классами

305.

Поэтому переопределять его
следует только в том случае,
если необходимо задать
отличающиеся действия

306.

307.

308.

Абстрактный базовый класс

309.

Чаще всего базовые классы
предназначены для представления
общих понятий, которые
предполагается конкретизировать
в производных классах

310.

Очевидно, что объекты таких
классов создавать бессмысленно
(например, класс figure)

311.

Базовый класс важен
исключительно как абстрактный
класс, определяющий общие
принципы работы его потомков

312.

В языке C++ существует
возможность зафиксировать эту
абстрактность на уровне самого
языка

313.

Для этого используются чисто
виртуальные функции

314.

Чисто виртуальный метод –
это метод, который в базовом
классе только объявляется, но
не определяется
virtual void calculateArea ()=0;

315.

316.

Базовый класс, который
содержит хотя бы один чисто
виртуальный метод называется
абстрактным базовым классом

317.

Абстрактный класс может
использоваться только в
качестве базового для других
классов — объекты абстрактного
класса создавать нельзя

318.

Однако можно создавать
указатель или ссылку на
абстрактный базовый класс

319.

Абстрактный класс можно
рассматривать как заготовку, в
которой часть функциональности
реализована, а оставшаяся часть
делегирована потомкам

320.

Важно понимать, что производный
класс, который наследуется от
абстрактного базового класса,
должен переопределить все чисто
виртуальные методы

321.

В противном случае производный
класс также будет считаться
абстрактным

322.

Таким образом, можно создать
функцию, параметром которой
является указатель на
абстрактный класс

323.

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

324.

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

325.

Полиморфная функция

326.

Таким образом, полиморфизм
предполагает один интерфейс и
множество реализаций

327.

Динамическая идентификация
типов (Run-Time Type
Identification, RTTI)

328.

Механизм идентификации типа
во время выполнения программы
позволяет определять, на какой
тип в текущий момент времени
ссылается указатель

329.

Для доступа к RTTI в стандарт
языка введен оператор typeid и
класс type_info

330.

Формат оператора typeid:
typeid (тип)
typeid (выражение)

331.

Оператор принимает в качестве
параметра имя типа или
выражение и возвращает ссылку
на объект класса type_info,
содержащий информацию о типе

332.

333.

334.

Операторы == и != позволяют
сравнивать два объекта на
равенство и неравенство

335.

Метод name() возвращает
указатель на строку,
представляющую имя типа,
описываемого объектом класса
type_info

336.

Полиморфное приведение типов
с использованием оператора
dynamic_cast

337.

Оператор dynamic_cast
применяется для преобразования
указателей родственных классов
иерархии

338.

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

339.

Формат оператора:
dynamic_cast <тип *> (выражение)

340.

При этом во время выполнения
программы производится
проверка допустимости
преобразования

341.

Для того чтобы проверка
допустимости могла быть
выполнена, аргумент оператора
dynamic_cast должен быть
полиморфного типа, т.е. иметь
хотя бы один виртуальный метод

342.

Если преобразование оказалось
некорректным, то оно не
выполняется, и оператор вернет
нулевой указатель

343.

344.

345.

346.

Обработка исключительных
ситуаций

347.

Исключение – это временный
объект, создаваемый программой
в случае возникновения ошибки

348.

Исключение будет существовать
до тех пор, пока его не обработают

349.

Синтаксис создания
(вбрасывания) исключения:
throw значение;

350.

Исключение может быть объектом
любого типа - как стандартного,
так и пользовательского

351.

Механизм обработки исключений
- это способ обработки ошибок
средствами языка C++

352.

Синтаксис обработки
исключений
try
{
// код, подлежащий проверке на наличие ошибок
throw <выражение>
//генерация исключения указанного типа
}
catch(<тип_исключения>)
{
//обработка исключения
}

353.

Файловый ввод/вывод
средствами языка С++

354.

Поток — это абстрактное
понятие, относящееся к любому
переносу данных от источника к
приемнику

355.

Поток определяется как
последовательность байтов и не
зависит от конкретного устройства,
с которым производится обмен

356.

Физическим устройством может
быть клавиатура, монитор, файл,
оперативная память, принтер и т.д.

357.

Обмен с потоком для увеличения
скорости передачи данных
производится, как правило, через
специальную область оперативной
памяти — буфер потока

358.

Фактическая передача данных
выполняется при выводе после
заполнения буфера, а при вводе —
если буфер исчерпан

359.

При этом чтение данных из потока
называется извлечением, а вывод
данных в поток — включением

360.

Вывод данных в поток

361.

Чтение данных из потока

362.

По направлению обмена потоки
можно разделить на входные,
выходные и двунаправленные

363.

Входные потоки - потоки, из
которых читаются данные

364.

Выходные потоки - потоки, в
которые записываются данные

365.

Двунаправленные потоки потоки, допускающие как чтение,
так и запись

366.

Стандартная библиотека
содержит три класса для работы
с файлами:
• ifstream — класс входных
файловых потоков
• ofstream— класс выходных
файловых потоков
• fstream — класс двунаправленных
файловых потоков

367.

Эти классы являются
производными от классов
istream, ostream и iostream
соответственно

368.

Объект класса ifstream
представляет собой входной
файловый поток для чтения
информации из файла

369.

Объект класса ofstream
представляет собой выходной
файловый поток для записи
информации в файл

370.

Объект класса fstream
представляет собой
двунаправленный файловый
поток для чтения и записи

371.

Режимы открытия файла

372.

Стандартная библиотека С++

373.

Стандартная библиотека
шаблонов (STL) (Standard
Template Library) - это составная
часть стандартной библиотеки
языка С++

374.

STL - это набор шаблонных
классов и функций общего
назначения, реализующих
наиболее популярные структуры
данных и часто употребительные
алгоритмы работы с ними

375.

Архитектура STL была
разработана Александром
Степановым и Менг Ли

376.

STL состоит из следующих
компонентов:
контейнеры (containers)
адаптеры (adaptors)
итераторы (iterators)
алгоритмы (algorithms)
функторы (functors)
предикаты (predicates)

377.

Контейнер предназначен для
хранения набора объектов в
памяти

378.

Два основных типа контейнеров:
последовательные и
ассоциативные

379.

Последовательный контейнер –
упорядоченная коллекция, в
которой каждый элемент имеет
определенную позицию (vector, list)

380.

Позиция зависит от места
вставки, но не зависит от
значения элемента

381.

Ассоциативный контейнер –
коллекция элементов, в которой
позиция элемента зависит от его
значения и выбранного критерия
сортировки (map, set)

382.

Такой контейнер всегда находится
в отсортированном состоянии, что
ускоряет выполнение поиска

383.

Адаптер – специализированный
контейнер, который
предоставляет определенный
интерфейс для доступа к данным
(stack, queue)

384.

Итератор – это специальный
указатель, который используется
для перемещения по контейнеру
и для манипулирования
объектами, находящимися в
контейнере

385.

Итераторы делятся на 5
категорий:
итератор ввода
итератор вывода
прямой итератор
двусторонний итератор
итератор произвольного
доступа

386.

Итератор ввода (InputIterator)
перемещается только вперед и
поддерживает только чтение

387.

Итератор вывода (OutputIterator)
перемещается только вперед и
поддерживает только запись

388.

Прямой итератор
(ForwardIterator) перемещается
только вперед, позволяет
выполнять чтение и запись

389.

Двусторонний итератор
(BidirectionalIterator) - прямой
итератор, который поддерживает
перебор элементов в обратном
порядке

390.

Итератор произвольного доступа
(RandomAccessIterator) имеет все
свойства двустороннего
итератора, а также поддерживает
произвольный доступ к элементам

391.

Алгоритмы – функции, которые
используются для обработки
элементов в контейнере
(например, сортировка, поиск)

392.

Алгоритмы используют итераторы

393.

Так как каждый класс контейнера
имеет итератор, один и тот же
алгоритм может работать с
различными контейнерами

394.

Функторы – это объекты,
действующие как функции, они
могут быть объектами класса или
указателями на функцию

395.

Функторы позволяют выполнять
конфигурирование алгоритмов для
специального использования

396.

Предикаты - функции, которые
проверяют, удовлетворяет ли
объект заданным критериям, и
возвращают значение типа bool

397.

Предикаты используются,
например, в поисковых
алгоритмах для задания более
сложного критерия поиска
English     Русский Rules