- •Список литературы по модулю
- •История языка C++
- •Основные особенности C++
- •Простые расширения языка C
- •Объявление переменных ссылочного типа
- •Инициализация и использование ссылок
- •Ссылки в формальных параметрах функций
- •Ссылки как возвращаемые значения функций
- •Константные ссылки
- •Объявление класса
- •Секции в объявлении класса
- •Пример: секции в объявлении класса
- •Объявление полей
- •Определения статических полей
- •Объявление методов
- •Виртуальные и абстрактные методы
- •Объявление конструкторов
- •Пример: объявление конструкторов
- •Создание объектов в динамической памяти
- •Создание массивов в динамической памяти
- •Удаление объектов и массивов
- •Объявление деструктора
- •Пример: объявление деструктора
- •Объекты в автоматической памяти
- •Пример: автоматический вызов деструктора
- •Пример: автоматический вызов деструктора (продолжение)
- •Объекты в глобальной памяти
- •Объекты в полях других объектов
- •Пример: объекты в полях других объектов
- •Проблема копирования объектов
- •Объявление конструктора копий
- •Перегруженная операция присваивания
- •Основной способ наследования в C++
- •Пример: одиночное наследование
- •Переопределение методов
- •Пример: переопределение методов
- •Динамическое приведение типов
- •Пример: динамическое приведение типов не всегда допустимо
- •Пример: динамическое приведение типов
- •private- и protected-наследование
- •Наследование от нескольких базовых классов
- •Иерархия наследования и классы противоречия
- •Неоднозначности в противоречивых иерархиях
- •Разрешение неоднозначностей
- •Основная проблема противоречивых иерархий
- •Виртуальное наследование
- •Пример: виртуальное наследование
- •Понятие шаблона
- •Типовые формальные параметры шаблона
- •Нетиповые формальные параметры шаблона
- •Шаблонные формальные параметры шаблона
- •Значения параметров шаблона по умолчанию
- •Зависимые идентификаторы в шаблоне
- •Инстанциация шаблонов
- •Выведение фактических параметров при инстанциации шаблона функции
- •Требования к фактическим параметрам шаблонов
- •Специализация шаблона функции
- •Пример: специализация шаблона функции
- •Пример: перегрузка имеет больший приоритет, чем специализация
- •Cпециализация шаблона класса
- •Пример: специализация шаблона класса
- •Частичная специализация шаблона класса
- •Вычисления во время компиляции
- •Пример: возведение числа в степень
- •Понятие перегрузки операций
- •Ассортимент перегружаемых операций
- •Перегрузка операции присваивания
- •Операция присваивания возвращает левое значение
- •Составные операции присваивания
- •Перегрузка бинарных арифметических операций
- •Перегрузка операций сравнения
- •Перегрузка операций с помощью функций
- •Перегрузка унарных операций
- •Перегрузка операции приведения типа
- •Исключения
- •Оператор throw
- •Пример: оператор throw
- •Синтаксис try- и catch-блоков
- •Пример: перехват исключения std::bad_alloc
- •Жизненный цикл объектов-исключений
- •Пример 1: жизненный цикл объектов-исключений
- •Пример 2: жизненный цикл объектов-исключений
- •Пример 3: жизненный цикл объектов-исключений
- •Пример: уничтожение автоматических объектов в процессе передачи исключения в catch-блок
- •Перехват исключений в инициализаторах конструкторов
- •Пример: перехват исключений в инициализаторах конструкторов
- •Спецификатор throw в заголовках функций
- •Пример 1: спецификатор throw
- •Пример 2: спецификатор throw
- •Спецификатор throw и переопределение виртуальных методов
- •Создание классов исключений
- •Пример: создание классов исключений
Операция присваивания возвращает левое значение
Базовые
сведения
Обобщённое программирова- ние
Перегрузка
операций
Форма перегрузки операции присваивания в C++ наводит на мысль, что она возвращает левое значение, т.е. результату, возвращаемому операцией присваивания, можно чего-то присвоить:
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
A x , y , z;
(x = y) = z;
Этот код действительно работает. Более того, в отличие от языка C, язык C++ допускает такое использование операции присваивания и для встроенных типов данных. Например,
int a = 2, b = 3, c = 4; (a = b) = c;
Поэтому не стоит пытаться запретить такое поведение путём, например, возвращения константой ссылки:
const A& operator = ( const A & obj );
70 / 99
Составные операции присваивания
Базовые
сведения
Обобщённое программирова- ние
Перегрузка
операций
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
Составные операции присваивания перегружаются по той же схеме, что и обычная операция присваивания:
A& operator += ( const A & obj );
Как правило, в случае сложного внутреннего состояния объекта реализация перегруженной составной операции присваивания также должна предусматривать возможность присваивания объекта самому себе.
Составные операции присваивания также возвращают левое значение, обеспечивая работоспособность конструкций вида
(x += y) *= z;
71 / 99
Перегрузка бинарных арифметических операций
Базовые
сведения
Обобщённое программирова- ние
Перегрузка
операций
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
Прототип перегруженной бинарной арифметической операции может выглядеть как
const A& operator + ( const A & other ) const ;
Отметим, что ключевое слово const в конце прототипа метода означает, что метод не меняет внутреннее состояние объекта, для которого он вызван. Если объект – константный, то к нему применимы только константные методы! Удобно реализовать бинарные арифметические операции через уже реализованные операции составного присваивания:
const A& A :: operator + |
( const A & other ) const { |
return A (* this ) += |
other ; |
} |
|
А вот так делать не надо (лишний вызов конструктора копий + вызов деструктора):
const A A :: operator + ( const A & other ) const { A result = * this ; result += other ; return result ;
} |
72 / 99 |
|
Перегрузка операций сравнения
Базовые
сведения
Обобщённое программирова- ние
Перегрузка
операций
Введение
Присваивание
Бинарные
операции
Унарные опе-
рации
Операция ()
Исключения
Операции сравнения при перегрузке имеют следующие прототипы:
bool |
operator == |
( const |
A & other ) const ; |
bool |
operator != |
( const |
A & other ) const ; |
bool |
operator < |
( const |
A & other ) const ; |
bool |
operator > |
( const |
A & other ) const ; |
bool |
operator <= |
( const |
A & other ) const ; |
bool |
operator >= |
( const |
A & other ) const ; |
При этом удобно при реализации одних операций сравнения использовать уже реализованные другие операции. Например, реализовав операцию «==», мы можем использовать её отрицание в коде операции «!=»:
const bool A :: operator != ( const A & other ) const { return !(* this == other );
}
Этот приём, в частности, автоматически обеспечивает
непротиворечивость реализации операций сравнения.
73 / 99