Share
Embed
Программирование – 1 курс весна 2022 – 9 занятие
ТиМПИ
April 19, 2022
Transcript
30 slides
-
2/30 2/30 Перегруженный оператор • позволяет применять встроенные операторы языка
к разным типам, в том числе и пользовательским • функция со специальным именем: ключевое слово «оператор», за которым следует символ определяемого оператора. Как и любая другая функция, перегруженный оператор имеет тип возвращаемого значения и список параметров • всего лишь более удобный способ вызова функций → должно упрощать написание кода • перегрузка возможна только для пользовательских типов/классов Важно! -
3/30 3/30 Общие правила при выборе перегружаемого оператора • Смысл
перегруженного оператора должен быть очевиден для пользователя Например, использование операторов • + и += для конкатенации экземпляров std::basic_string<> • / и /= для конкатенации элементов пути std::filesystem::path • Приоритет и ассоциативность операторов при перегрузке не меняются std::сout<<c?x:y; это (std::сout<<c)?x:y; а не std::сout<<(c?x:y); -
4/30 4/30 Операторы, не рекомендуемые для перегрузки , && ||
Стандарт предусматривает • порядок вычисления операндов (слева направо) • для && и || еще и семантику быстрых вычислений & осторожно при использовании с шаблонами -
14/30 14/30 Интерфейс и семантика перегруженных операторов • оператор присваивания
должен возвращать ссылку на левый операнд, которая может быть использована как правый операнд в другом присваивании. a=b=c • операторы сравнения должны возвращать bool и не изменять операнды • унарные операторы +, –, ~ должны возвращать модифицированное значение и не изменять операнд -
15/30 15/30 Реализация перегрузки операторов • как функция-член • как
свободная функцию -
17/30 17/30 Ещё особенности • Множественная перегрузка • Для унарных
— с const и без него (для функций-членов) — параметр типа константная или обычная ссылка (для свободных функций) • Для бинарных операторов и оператора () количество перегрузок не ограничено. • Особенности перегрузки операторов с использованием свободных функций • Симметрия • Неявные преобразования • Расширение интерфейса класса -
18/30 18/30 Определение дружественной свободной функции внутри класса Дружественные функции
имеют доступ к приватным методам класса или структуры -
19/30 19/30 Особенности перегрузки некоторых операторов Оператор –> Общая форма
класса, в котором перегружен оператор –> -
20/30 20/30 Оператор [] • к этому оператору запрещено применять
«дружественные» функции Вариант 1. Оператор [] должен быть использован только в правой части оператора присваивания. То есть значение элемента массива в классе не изменяется. Вариант 2. Оператор [] должен размещаться в левой и правой части оператора присваивания. Можно изменять значения элементов массива по индексу. -
21/30 21/30 Оператор [] 2/2 • можно реализовать только как
функцию-член • может иметь любое число параметров любого типа, тип возвращаемого значения также произвольный • классы, с перегруженным оператором (), называются функциональными, их экземпляры называются функциональными объектами или функторами -
22/30 22/30 Операторы сравнения < • антисимметричность (если x<y равно
true, то y<x равно false) • транзитивность (если x<y и y<z, то x<z) • иррефлексивность (x<x всегда равно false) • транзитивная эквивалентность (если !(x<y) && !(y<x) и !(y<z) && !(z<y), то !(x<z) && !(z<x)) == • Симметричность (если x==y, то y==x) • Транзитивность (если x==y и y==z, то x==z) • Рефлексивность (x==x всегда равно true) -
24/30 24/30 Инкремент, декремент 1/2 Для того, чтобы при реализации
в классе, отличить префиксную и постфиксную формы реализации операторной функции ++ или --, нужно придерживаться следующих правил: • если перегружается префиксная форма оператора ++ / --, то в классе нужно реализовать операторную функцию operator++() / operator--() без параметров; • если перегружается постфиксная форма оператора ++ / --, то в классе нужно реализовать операторную функцию operator++(int d) / operator--(int d) с одним параметром. Параметр d необходим для указания того, что перегружается именно постфиксная реализация оператора -
29/30 29/30 Рекомендации к форме определения операторов Роб Мюррей, в
своей книге «C++ Strategies and Tactics» определил следующие рекомендации по выбору формы оператора: Оператор Рекомендуемая форма Все унарные операторы Член класса = () [] -> ->* Обязательно член класса += -= /= *= ^= &= |= %= >>= <<= Член класса Остальные бинарные операторы Не член класса