- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
a.operator sym(b); // класс а содержит оператор sym как функцию-член
operator sym(a, b); // оператор sym - обычная функция
В отличие от обычных вызовов функции, нельзя использовать форму вызова для различения функции-члена или не члена класса.
Когда используется перегруженный оператор с операндом типа класса, функции-кандидаты включают обычные версии, не являющиеся членами класса этого оператора, а также его встроенные версии. Кроме того, если левый операнд имеет тип класса, определенные в нем перегруженные версии оператора (если они есть) также включаются в набор кандидатов.
Когда вызывается именованная функция, функции-члены и не члены класса с тем же именем не перегружают друг друга. Перегрузки нет потому, что синтаксис, используемый для вызова именованной функции, различает функции- члены и не члены класса. При вызове через объект класса (или ссылку, или указатель на такой объект) рассматриваются только функции-члены этого класса. При использовании в выражении перегруженного оператора нет никакого способа указать на использование функции-члена или не члена класса. Поэтому придется рассматривать версии и функции-члены, и не члены класса.
Набор функций-кандидатов для используемого в выражении оператора может содержать функции-члены и не члены класса.
Определим, например, оператор суммы для класса SmallInt:
class SmallInt {
friend
SmallInt operator*(const SmallInt&, const SmallInt&);
public:
SmallInt(int = 0); // преобразование из int
operator int() const { return val; } // преобразование в int
private:
std::size_t val;
};
Этот класс можно использовать для суммирования двух объектов класса SmallInt, но при попытке выполнения смешанных арифметических операций возникнет проблема неоднозначности:
SmallInt s1, s2;
SmallInt s3 = s1 + s2; // использование перегруженного оператора +
int i = s3 + 0; // ошибка: неоднозначность
Первый случай суммирования использует перегруженную версию оператора + для суммирования двух значений типа SmallInt. Второй случай неоднозначен, поскольку 0 можно преобразовать в тип SmallInt и использовать версию оператора + класса SmallInt либо преобразовать объект s3 в тип int и использовать встроенный оператор суммы для типа int.
Предоставление функции преобразования в арифметический тип и перегруженных операторов для того же типа может привести к неоднозначности между перегруженными и встроенными операторами.
Упражнения раздела 14.9.3Упражнение 14.52. Какой из операторов operator+, если таковые вообще имеются, будет выбран для каждого из следующих выражений суммы? Перечислите функции-кандидаты, подходящие функции и преобразования типов для аргументов каждой подходящей функции:
struct LongDouble {
// оператор-член operator+ только для демонстрации;
// обычно он не является членом класса
LongDouble operator+(const SmallInt&); // другие члены как в p. 14.9.2
};
LongDouble operator+(LongDouble&, double);
SmallInt si;
LongDouble ld;
ld = si + ld;
ld = ld + si;
Упражнение 14.53. С учетом определения класса SmallInt определите, допустимо ли следующее выражение суммы. Если да, то какой оператор суммы используется? В противном случае, как можно изменить код, чтобы сделать его допустимым?
SmallInt s1;
double d = s1 + 3.14;
Резюме
Перегруженный оператор должен либо быть членом класса, либо иметь по крайней мере один операнд типа класса. У перегруженных операторов должно быть то же количество операндов, порядок и приоритет, как у соответствующего оператора встроенного типа. Когда оператор определяется как член класса, его неявный указатель this связан с первым операндом. Операторы присвоения, индексирования, вызова функции и стрелки должны быть членами класса.
Объекты классов, которые перегружают оператор вызова функции, operator() называются "объектами функций". Такие объекты зачастую используются в комбинации со стандартными алгоритмами. Лямбда-выражения — это отличный способ определения простых классов объектов функции.
Класс может определить преобразования в или из своего типа, которые будут использованы автоматически. Неявные конструкторы, которые могут быть вызваны с одним аргументом, определяют преобразования из типа параметра в тип класса; операторы неявного преобразования определяют преобразования из типа класса в другие типы.
Термины
Объект функции (function object). Объект класса, в котором определен перегруженный оператор вызова. Объекты функций применяются там, где обычно ожидаются функции.
Оператор преобразования (conversion operator). Оператор преобразования — это функция-член, которая осуществляет преобразование из типа класса в другой тип. Операторы преобразования должны быть константными членами их класса. Такие функции не получают параметров и не имеют типа возвращаемого значения. Они возвращают значение типа оператора преобразования. То есть оператор operator int возвращает тип int, оператор operator string — тип string и т.д.
Перегруженный оператор (overloaded operator). Функция, переопределяющая значение одного из встроенных операторов. Функция перегруженного оператора имеет имя operator с последующим определяемым символом. У перегруженных операторов должен быть по крайней мере один операнд типа класса. У перегруженных операторов тот же приоритет, порядок и количество операндов, что и у их встроенных аналогов.
Пользовательское преобразование (user-defined conversion). Синоним термина преобразование типа класса.
Преобразование типа класса (class-type conversion). Преобразования в или из типа класса определяются конструкторами и операторами преобразования соответственно. Неявные конструкторы, получающие один аргумент, определяют преобразование из типа аргумента в тип класса. Операторы преобразования определяют преобразования из типа класса в заданный тип.
Сигнатура вызова (call signature). Представляет интерфейс вызываемого объекта. Сигнатура вызова включает тип возвращаемого значения и заключенный в круглые скобки разделяемый запятыми список типов аргументов.
Таблица функций (function table). Контейнер, как правило, карта или вектор, содержащий значения, позволяющие выбрать и выполнить функцию во время выполнения.
Шаблон функции (function template). Библиотечный шаблон, способный представить любой вызываемый тип.
Явный оператор преобразования (explicit conversion operator). Оператор преобразования с предшествующим ключевым словом explicit. Такие операторы используются для неявных преобразований только в определенных условиях.
Глава 15
Объектно-ориентированное программирование
Объектно-ориентированное программирование основано на трех фундаментальных концепциях: абстракция данных, наследование и динамическое связывание.
Наследование и динамическое связывание рационализируют программы двумя способами: они упрощают создание новых классов, которые подобны, но не идентичны другим классам, а также облегчают написание программы, позволяя игнорировать незначительные различия в подобных классах.
При создании большинства приложений используются одинаковые принципы, которые различаются лишь способами их реализации. Например, рассматриваемый для примера книжный магазин мог бы применять различные системы тарификации для разных книг. Некоторые книги можно было бы продавать лишь по фиксированной цене, а для других применить гибкую систему скидок. Можно было бы предоставлять скидку тем покупателям, которые покупают несколько экземпляров книги. Скидку можно было бы также предоставить на несколько первых экземпляров, а для остальных оставить полную цену. Объектно-ориентированное программирование (Object-Oriented Programming, или ООП) — это наилучший способ создания приложений такого типа.
15.1. Краткий обзор ООП
Ключевыми концепциями объектно-ориентированного программирования являются абстракция данных, наследование и динамическое связывание. Используя абстракцию данных, можно определить классы, отделяющие интерфейс от реализации (см. главу 7). Наследование позволяет определять классы, моделирующие отношения между подобными типами. Динамическое связывание позволяет использовать объекты этих типов, игнорируя незначительные различия между ними.

