- •Список литературы по модулю
- •История языка C++
- •Основные особенности C++
- •Простые расширения языка C
- •Объявление переменных ссылочного типа
- •Инициализация и использование ссылок
- •Ссылки в формальных параметрах функций
- •Ссылки как возвращаемые значения функций
- •Константные ссылки
- •Объявление класса
- •Секции в объявлении класса
- •Пример: секции в объявлении класса
- •Объявление полей
- •Определения статических полей
- •Объявление методов
- •Виртуальные и абстрактные методы
- •Объявление конструкторов
- •Пример: объявление конструкторов
- •Создание объектов в динамической памяти
- •Создание массивов в динамической памяти
- •Удаление объектов и массивов
- •Объявление деструктора
- •Пример: объявление деструктора
- •Объекты в автоматической памяти
- •Пример: автоматический вызов деструктора
- •Пример: автоматический вызов деструктора (продолжение)
- •Объекты в глобальной памяти
- •Объекты в полях других объектов
- •Пример: объекты в полях других объектов
- •Проблема копирования объектов
- •Объявление конструктора копий
- •Перегруженная операция присваивания
- •Основной способ наследования в C++
- •Пример: одиночное наследование
- •Переопределение методов
- •Пример: переопределение методов
- •Динамическое приведение типов
- •Пример: динамическое приведение типов не всегда допустимо
- •Пример: динамическое приведение типов
- •private- и protected-наследование
- •Наследование от нескольких базовых классов
- •Иерархия наследования и классы противоречия
- •Неоднозначности в противоречивых иерархиях
- •Разрешение неоднозначностей
- •Основная проблема противоречивых иерархий
- •Виртуальное наследование
- •Пример: виртуальное наследование
- •Понятие шаблона
- •Типовые формальные параметры шаблона
- •Нетиповые формальные параметры шаблона
- •Шаблонные формальные параметры шаблона
- •Значения параметров шаблона по умолчанию
- •Зависимые идентификаторы в шаблоне
- •Инстанциация шаблонов
- •Выведение фактических параметров при инстанциации шаблона функции
- •Требования к фактическим параметрам шаблонов
- •Специализация шаблона функции
- •Пример: специализация шаблона функции
- •Пример: перегрузка имеет больший приоритет, чем специализация
- •Cпециализация шаблона класса
- •Пример: специализация шаблона класса
- •Частичная специализация шаблона класса
- •Вычисления во время компиляции
- •Пример: возведение числа в степень
- •Понятие перегрузки операций
- •Ассортимент перегружаемых операций
- •Перегрузка операции присваивания
- •Операция присваивания возвращает левое значение
- •Составные операции присваивания
- •Перегрузка бинарных арифметических операций
- •Перегрузка операций сравнения
- •Перегрузка операций с помощью функций
- •Перегрузка унарных операций
- •Перегрузка операции приведения типа
- •Исключения
- •Оператор throw
- •Пример: оператор throw
- •Синтаксис try- и catch-блоков
- •Пример: перехват исключения std::bad_alloc
- •Жизненный цикл объектов-исключений
- •Пример 1: жизненный цикл объектов-исключений
- •Пример 2: жизненный цикл объектов-исключений
- •Пример 3: жизненный цикл объектов-исключений
- •Пример: уничтожение автоматических объектов в процессе передачи исключения в catch-блок
- •Перехват исключений в инициализаторах конструкторов
- •Пример: перехват исключений в инициализаторах конструкторов
- •Спецификатор throw в заголовках функций
- •Пример 1: спецификатор throw
- •Пример 2: спецификатор throw
- •Спецификатор throw и переопределение виртуальных методов
- •Создание классов исключений
- •Пример: создание классов исключений
Пример: переопределение методов
Базовые |
|
Переопределим метод draw в производном классе Dog: |
|||
|
|
|
|
||
сведения |
|
|
|
|
|
Введение |
18 |
class Dog : public |
Animal |
||
Ссылки |
|||||
19 |
{ |
|
|
||
Классы |
|
|
|||
20 |
private : |
|
|
||
Поля и методы |
|
|
|||
21 |
char * breed ; |
|
|||
Конструкторы |
|
||||
|
public : |
|
|
||
Создание и |
22 |
|
|
||
|
|
|
|
||
уничтожение 23 |
Dog ( char |
* bread ); |
|||
объектов |
24 |
virtual |
void |
draw (); |
|
Копирование |
|||||
|
|
|
|
объектов |
25 |
}; |
Одиночное |
26 |
|
наследование |
||
|
Множественное |
27 |
наследование |
28 |
|
Обобщённое |
29 |
программирова-
ние |
30 |
|
|
Перегрузка |
31 |
|
|
операций |
32 |
|
Исключения |
33 |
34
35
Dog :: Dog ( char * bread ):
Animal (" Canis lupus familiaris "), breed ( breed ) {}
void Dog :: draw () { |
|
|
|
|
cout << " |
/ |
| __ |
\n" |
|
" |
( |
|
@ ‘ ___ |
\n" |
" |
/ |
|
|
O \n" |
" |
/ |
( _____ / |
\n" |
|
" |
/ _____ / |
U |
\n"; |
36 }
38 / 99
Динамическое приведение типов
Базовые
сведения
Введение
Ссылки
Классы
Поля и методы
Конструкторы
Создание и уничтожение объектов Копирование
объектов
Одиночное
наследование
Множественное наследование
Обобщённое |
программирова- |
ние |
Перегрузка
операций
Исключения
Операция динамического приведения объекта obj к типу T проверяет, является ли тип T одним из типов объекта obj, и возвращает obj, если является. В противном случае операция либо возвращает нулевой указатель, либо порождает исключение.
В C++ операция динамического приведения типа может применяться к указателям и ссылкам на объекты и записывается как
dynamic_cast <T > ( obj )
Так как нулевых ссылок не существует, то при неудачном приведении порождается исключение std::bad_cast.
39 / 99
Пример: динамическое приведение типов не всегда допустимо
Базовые |
1 |
class |
Animal {}; |
|
|
сведения |
2 |
class |
Dog : public |
Animal {}; |
|
Введение |
|||||
3 |
class |
Cat : public |
Animal {}; |
||
Ссылки |
|||||
|
|
|
|
||
Классы |
4 |
|
|
|
|
|
int main () |
|
|||
Поля и методы |
5 |
|
|||
|
|
|
|
||
Конструкторы |
6 |
{ |
|
|
Создание и |
7 |
Animal |
*a |
= |
new |
Dog (); |
|
||
уничтожение |
8 |
Dog |
* dog |
= |
dynamic_cast < Dog *> |
(a ); |
|||
объектов |
|||||||||
|
|
|
|
|
|
|
|
||
Копирование |
9 |
cout |
<< |
dog ; |
|
|
|||
объектов |
10 |
return |
0; |
|
|
|
|
||
Одиночное |
|
|
|
|
|||||
|
} |
|
|
|
|
|
|
||
наследование |
11 |
|
|
|
|
|
|
Множественное
наследование
Обобщённое
программирова-
ние
Перегрузка
операций
g++ выдаёт ошибку:
cannot dynamic_cast ’a ’ ( of type |
’ class Animal * ’) to |
type ’ class Dog *’ ( source type is |
not polymorphic ) |
|
|
|
|
|
Т.к. в классе Dog нет виртуальных методов, то для эконо- |
|
|
|
|
|
|
|
|
|
Исключения |
мии памяти объект этого класса не содержит информации о |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
типе, тем самым делая невозможным динамическое приве- |
|
|
|
|
|
|
|
|
|
|
|
дение типов. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Пример: динамическое приведение типов
Базовые |
1 |
class |
Animal |
|
сведения |
2 |
{ |
|
|
Введение |
|
|
||
3 |
public : |
|
||
Ссылки |
|
|||
|
virtual void |
f () {} |
||
Классы |
4 |
|||
|
}; |
|
|
|
Поля и методы |
5 |
|
|
|
|
|
|
|
|
Конструкторы |
6 |
class |
Dog : public |
Animal {}; |
Создание и |
7 |
class |
Cat : public |
Animal {}; |
уничтожение |
|
|
|
|
объектов |
8 |
|
Копирование |
9 |
int |
main () |
|
|
|
|
объектов |
10 |
{ |
|
|
|
|
|
Одиночное |
|
|
|
|
|
||
|
|
Animal |
*a |
= new Dog () , *b = new Cat (); |
|||
наследование |
11 |
|
|||||
Множественное |
12 |
|
Dog |
*x |
= |
dynamic_cast < Dog *> |
(a), |
наследование |
13 |
|
|
*y |
= |
dynamic_cast < Dog *> |
(b ); |
Обобщённое |
|
|
|||||
14 |
|
cout |
<< |
x |
<< " , " << y; |
|
|
программирова- |
|
|
|||||
|
|
return |
0; |
|
|
||
ние |
15 |
|
|
|
Перегрузка |
16 } |
операций |
|
Исключения Вывод:
0 x603010 , 0
41 / 99