
- •Список литературы по модулю
- •История языка C++
- •Основные особенности C++
- •Простые расширения языка C
- •Объявление переменных ссылочного типа
- •Инициализация и использование ссылок
- •Ссылки в формальных параметрах функций
- •Ссылки как возвращаемые значения функций
- •Константные ссылки
- •Объявление класса
- •Секции в объявлении класса
- •Пример: секции в объявлении класса
- •Объявление полей
- •Определения статических полей
- •Объявление методов
- •Виртуальные и абстрактные методы
- •Объявление конструкторов
- •Пример: объявление конструкторов
- •Создание объектов в динамической памяти
- •Создание массивов в динамической памяти
- •Удаление объектов и массивов
- •Объявление деструктора
- •Пример: объявление деструктора
- •Объекты в автоматической памяти
- •Пример: автоматический вызов деструктора
- •Пример: автоматический вызов деструктора (продолжение)
- •Объекты в глобальной памяти
- •Объекты в полях других объектов
- •Пример: объекты в полях других объектов
- •Проблема копирования объектов
- •Объявление конструктора копий
- •Перегруженная операция присваивания
- •Основной способ наследования в C++
- •Пример: одиночное наследование
- •Переопределение методов
- •Пример: переопределение методов
- •Динамическое приведение типов
- •Пример: динамическое приведение типов не всегда допустимо
- •Пример: динамическое приведение типов
- •private- и protected-наследование
- •Наследование от нескольких базовых классов
- •Иерархия наследования и классы противоречия
- •Неоднозначности в противоречивых иерархиях
- •Разрешение неоднозначностей
- •Основная проблема противоречивых иерархий
- •Виртуальное наследование
- •Пример: виртуальное наследование
- •Понятие шаблона
- •Типовые формальные параметры шаблона
- •Нетиповые формальные параметры шаблона
- •Шаблонные формальные параметры шаблона
- •Значения параметров шаблона по умолчанию
- •Зависимые идентификаторы в шаблоне
- •Инстанциация шаблонов
- •Выведение фактических параметров при инстанциации шаблона функции
- •Требования к фактическим параметрам шаблонов
- •Специализация шаблона функции
- •Пример: специализация шаблона функции
- •Пример: перегрузка имеет больший приоритет, чем специализация
- •Cпециализация шаблона класса
- •Пример: специализация шаблона класса
- •Частичная специализация шаблона класса
- •Вычисления во время компиляции
- •Пример: возведение числа в степень
- •Понятие перегрузки операций
- •Ассортимент перегружаемых операций
- •Перегрузка операции присваивания
- •Операция присваивания возвращает левое значение
- •Составные операции присваивания
- •Перегрузка бинарных арифметических операций
- •Перегрузка операций сравнения
- •Перегрузка операций с помощью функций
- •Перегрузка унарных операций
- •Перегрузка операции приведения типа
- •Исключения
- •Оператор throw
- •Пример: оператор throw
- •Синтаксис try- и catch-блоков
- •Пример: перехват исключения std::bad_alloc
- •Жизненный цикл объектов-исключений
- •Пример 1: жизненный цикл объектов-исключений
- •Пример 2: жизненный цикл объектов-исключений
- •Пример 3: жизненный цикл объектов-исключений
- •Пример: уничтожение автоматических объектов в процессе передачи исключения в catch-блок
- •Перехват исключений в инициализаторах конструкторов
- •Пример: перехват исключений в инициализаторах конструкторов
- •Спецификатор throw в заголовках функций
- •Пример 1: спецификатор throw
- •Пример 2: спецификатор throw
- •Спецификатор throw и переопределение виртуальных методов
- •Создание классов исключений
- •Пример: создание классов исключений

Пример: возведение числа в степень
Базовые |
5 |
|
|
||
сведения |
6 |
|
Обобщённое |
7 |
|
|
||
программирова- |
8 |
|
ние |
||
9 |
||
Объявление |
||
|
||
шаблонов |
10 |
|
Порождение |
11 |
|
кода |
||
|
||
Специализация |
12 |
|
шаблонов |
13 |
|
|
||
Перегрузка |
14 |
|
операций |
||
|
||
|
15 |
|
Исключения |
16 |
|
|
||
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
|
21 |
|
|
22 |
|
|
23 |
|
|
24 |
|
|
25 |
|
|
26 |
template < typename T , int |
N > |
|
struct Power { |
|
|
static T eval (T x) { |
|
|
if (N % 2 == 0) |
{ |
|
return Power |
<T ,N /2 >:: eval (x*x ); |
}
return x * Power <T ,N -1 >:: eval (x );
}
}; |
|
|
template < typename T > |
||
struct |
Power <T ,0 > { |
|
static |
T eval (T x) { return (T )1; } |
|
}; |
|
|
int main () |
|
|
{ |
|
|
int |
x; |
|
cin |
>> |
x; |
cout << |
Power <int ,10 >:: eval (x) << ’\n ’; |
return |
0; |
} |
66 / 99 |

Понятие перегрузки операций
Базовые
сведения
Обобщённое программирова-
ние
Перегрузка
операций
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
Вообще, de facto практически в любом языке программирования операции перегружены. Например, в языке Pascal смысл операции «+» меняется в зависимости от типов операндов вплоть до того, что «сложение» строк означает их конкатенацию.
Язык C++ позволяет распространить принцип перегрузки на пользовательские типы данных, т.е. на классы. При этом, в отличие от языков, в которых пользователь может сам составлять знаки операций и задавать их приоритет и ассоциативность (например, ML или Haskell), ассортимент операций и их характеристики в C++ жёстко заданы.
Технически перегрузка операций в C++ реализована через определение функций со специальными именами вида «operator знак_операции», осуществляющих выполнение операций.
67 / 99

Ассортимент перегружаемых операций
Базовые
сведения
Обобщённое программирова-
ние
Перегрузка
операций
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
В языке C++ допускается перегрузка следующего набора операций:
// |
унарные : |
|
|
++ |
-- - + ! ~ * & ( тип ) |
||
// |
бинарные : |
|
|
= |
+= -= *= /= |
%= |
&= |= ^| <<= >>= |
+ |
- * / % & | |
^ |
<< >> |
== != > < >= <= |
|
||
&& |
|| |
|
|
[] |
-> ->* () |
, |
|
Кроме того, допускается перегружать операции «new» и «delete».
Перегруженные операции имеют те же приоритеты и ассоциативность, что и соответствующие операции над базовыми типами языка C++.
Нельзя перегружать операции «.», «.*», «? :», «sizeof», «dynamic_cast» и некоторые другие.
68 / 99

Перегрузка операции присваивания
Базовые
сведения
Обобщённое программирова-
ние
Перегрузка
операций
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
Операция присваивания для некоторого класса A перегружается путём объявления в классе метода, прототип которого выглядит как
A& operator = ( const A & obj );
Схема работы перегруженной операции присваивания:
1.проверить, не присваивается ли объект сам себе (если так, то перейти к пункту 5);
2.освободить память, используемую внутри объекта;
3.выделить память, в которую будет скопировано содержимое obj;
4.выполнить копирование данных;
5.вернуть *this.
Вызов перегруженной операции присваивания можно выполнять двумя способами:
a = b; |
// |
1- ый |
способ |
|
a. operator =( b ); |
// |
2- ой |
способ |
69 / 99 |