15.1.3. Разработка перегруженных операторов
15.1.3. Разработка перегруженных операторов
Операторы присваивания, взятия адреса и оператор “запятая” имеют предопределенный смысл, если операндами являются объекты типа класса. Но их можно и перегружать. Семантика всех остальных операторов, когда они применяются к таким операндам, должна быть явно задана разработчиком. Выбор предоставляемых операторов зависит от ожидаемого использования класса.
Начинать следует с определения его открытого интерфейса. Набор открытых функций-членов формируется с учетом операций, которые класс должен предоставлять пользователям. Затем принимается решение, какие функции стоит реализовать в виде перегруженных операторов.
* После определения открытого интерфейса класса проверьте, есть ли логическое соответствие между операциями и операторами: isEmpty() становится оператором “ЛОГИЧЕСКОЕ НЕ”, operator!().
* isEqual() становится оператором равенства, operator==().
* copy() становится оператором присваивания, operator=().
У каждого оператора есть некоторая естественная семантика. Так, бинарный + всегда ассоциируется со сложением, а его отображение на аналогичную операцию с классом может оказаться удобной и краткой нотацией. Например, для матричного типа сложение двух матриц является вполне подходящим расширением бинарного плюса.
Примером неправильного использования перегрузки операторов является определение operator+() как операции вычитания, что бессмысленно: не согласующаяся с интуицией семантика опасна.
Такой оператор одинаково хорошо поддерживает несколько различных интерпретаций. Безупречно четкое и обоснованное объяснение того, что делает operator+(), вряд ли устроит пользователей класса String, полагающих, что он служит для конкатенации строк. Если семантика перегруженного оператора неочевидна, то лучше его не предоставлять.
Эквивалентность семантики составного оператора и соответствующей последовательности простых операторов для встроенных типов (например, эквивалентность оператора +, за которым следует =, и составного оператора +=) должна быть явно поддержана и для класса. Предположим, для String определены как operator+(), так и operator=() для поддержки операций конкатенации и почленного копирования:
String s1( "C");
String s2( "++" );
s1 = s1 + s2; // s1 == "C++"
Но этого недостаточно для поддержки составного оператора присваивания
s1 += s2;
Его следует определить явно, так, чтобы он поддерживал ожидаемую семантику.
Упражнение 15.1
Почему при выполнении следующего сравнения не вызывается перегруженный оператор operator==(const String&, const String&):
"cobble" == "stone"
Упражнение 15.2
Напишите перегруженные операторы неравенства, которые могут быть использованы в таких сравнениях:
String != String
String != С-строка
C-строка != String
Объясните, почему вы решили реализовать один или несколько операторов.
Упражнение 15.3
Выявите те функции-члены класса Screen, реализованного в главе 13 (разделы 13.3, 13.4 и 13.6), которые можно перегружать.
Упражнение 15.4
Объясните, почему перегруженные операторы ввода и вывода, определенные для класса String из раздела 3.15, объявлены как глобальные функции, а не функции-члены.
Упражнение 15.5
Реализуйте перегруженные операторы ввода и вывода для класса Screen из главы
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Список операторов
Список операторов «Яндекс» позволяет вести поиск в отдельных элементах страницы или в связанной с ней информации. Обратите внимание на то, что при использовании операторов, в которых как параметр задается имя хоста (таких как url, host и др.), должно указываться главное
Приоритет операторов
Приоритет операторов Последний вопрос, который мы здесь разберем, — приоритет операторов. Как мы помним, приоритет влияет на порядок, в котором выполняются операторы в выражении.Пусть имеется следующее выражение:a = b + c — 10;В этом случае сначала к значению переменной b
26. Сохраняйте естественную семантику перегруженных операторов
26. Сохраняйте естественную семантику перегруженных операторов РезюмеПрограммисты ненавидят сюрпризы. Перегружайте операторы только в случае веских на то оснований, и сохраняйте при этом их естественную семантику. Если это оказывается сложным, возможно, вы неверно
27. Отдавайте предпочтение каноническим формам арифметических операторов и операторов присваивания
27. Отдавайте предпочтение каноническим формам арифметических операторов и операторов присваивания РезюмеЕсли можно записать а+b, то необходимо, чтобы можно было записать и a+=b. При определении бинарных арифметических операторов одновременно предоставляйте и их
Группировка операторов
Группировка операторов Операторы можно группировать, заключая их в круглые скобки.
Внутреннее представление перегруженных операций
Внутреннее представление перегруженных операций Подобно любому элементу программы C#, перегруженные операции представляются специальными элементами синтаксиса CIL. Откройте, например, компоновочный блок OverloadedOps.exe с помощью ildasm.exe. Как показано на рис. 9.1, перегруженные
9.1. Объявления перегруженных функций
9.1. Объявления перегруженных функций Теперь, научившись объявлять, определять и использовать функции в программах, познакомимся с перегрузкой – еще одним аспектом в C++. Перегрузка позволяет иметь несколько одноименных функций, выполняющих схожие операции над
15.1.2. Имена перегруженных операторов
15.1.2. Имена перегруженных операторов Перегружать можно только предопределенные операторы языка C++ (см. табл. 15.1).Таблица 15.1. Перегружаемые операторы+-*/%^&|~!,===++--==!=&&||+=-=/=%=^=&=|=*=&==[]()--*newnew[]deletedelete[]Проектировщик класса не вправе объявить перегруженным оператор с другим
Приоритет операторов
Приоритет операторов Приоритет определяет порядок, в котором операторы и создаваемые ими значения вычисляются в выражении.Когда выражение содержит несколько операторов одного и того же типа, операторы вычисляются слева направо, если только не существует конфликта,
Перегрузка операторов
Перегрузка операторов Си++ позволяет вам легко вводить новые типы данных. Так, например, вы можете определить класс для работы с комплексными числами или числами в полярной системе координат. Естественно, что удобнее всего проводить вычисления с объектами таких классов
3.3 Сводка операторов
3.3 Сводка операторов Операторы С++ систематически и полностью изложены в #с.9, прочитайте, пожалуйста, этот раздел. А здесь приводится краткая сводка и некоторые примеры.Синтаксис оператора – оператор: описание (*список_операторов opt*) выражение optif оператор if ( выражение )