- Любовные романы
- Фантастика и фэнтези
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
C++ - Страустрап Бьярн
Шрифт:
Интервал:
Закладка:
5. (*3) Модифицируйте класс string из предыдущего примера таким образом, чтобы строка копировалась только когда это необходимо. То есть, храните совместно используемое представление двух строк, пока одна из этих строк не бдет изменена. Не пытайтесь одновременно с этим иметь операцию выделения подстроки, которая может использваться в левой части.
6. (*4) Разработайте класс string с семантикой по значению, копированием с задержкой и операцией подстроки, которая может стоять в левой части.
7. (*2) Какие преобразования используются в каждом выражнии следующей программы:
struct X (* int i; X(int); operator+(int); *);
struct Y (* int i; Y(X); operator+(X); operator int(); *);
X operator* (X,Y); int f(X);
X x = 1; Y y = x; int i = 2;
main() (* i + 10; y + 10; y + 10 * y; x + y + i; x * x + i; f(7); f(y); y + y; 106 + y; *)
Определите X и Y так, чтобы они оба были целыми типами. Измените программу так, чтобы она работала и печатала значения всех допустимых выражений.
8. (*2) Определите класс INT, который ведет себя в точности как int. Подсказка: определите INT::operator int().
9. (*1) Определите класс RINT, который ведет себя в точноти как int за исключением того, что единственные возмоные операции – это + (унарный и бинарный), – (унарный и бинарный), *, /, %. Подсказка: не определяйте INT::operator int().
10. (*3) Определите класс LINT, ведущий себя как RINT, за исключением того, что имеет точность не менее 64 бит.
11. (*4) Определите класс, который реализует арифметику с произвольной точностью. Подсказка: вам надо управлять памятью аналогично тому, как это делалось для класса string.
12. (*2) Напишите программу, доведенную до нечитаемого сотояния с помощью макросов и перегрузки операций. Вот идея: определите для INT + так, чтобы он означал -, и наоборот, а потом с помощью макроопределения определите int как INT. Переопределение часто употребляемых фунций, использование параметров ссылочного типа и несколко вводящих в заблуждение комментариев помогут устроить полную неразбериху.
13. (*3) Поменяйтесь со своим другом программами, которые у вас получились в предыдущем упражнении. Не запуская ее попытайтесь понять, что делает программа вашего друга. После выполнения этого упражнения вы будете знать, чего следует избегать.
14. (*2) Перепишите примеры с comlpex (#6.3.1), tiny (#6.3.2) и string (#6.9) не используя friend функций. Используйте только функции члены. Протестируйте каждую из новых версий. Сравните их с версиями, в которых используются функции друзья. Еще раз посмотрите Упражнение 5.3.
15. (*2) Определите тип vec4 как вектор их четырех float. Определите operator[] для vec4. Определите операции +, -, *, /, =, +=, -=, *=, /= для сочетаний векторов и чсел с плавающей точкой.
16. (*3) Определите класс mat4 как вектор из четырех vec4. Определите для mat4 operator[], возвращающий vec4. Опрделите для этого типа обычные операции над матрицами. Определите функцию, выполняющие для mat4 исключение Гусса.
17. (*2) Определите класс vector, аналогичный vec4, но с длиной, которая задается как параметр конструктора vector::vector(int).
18. (*3) Определите класс matrix, аналогичный mat4, но с размерностью, задаваемой параметрами конструктора matrix::matrix(int,int).
Глава 7
Производные классы
Не надо размножать объекты без необходимости
У. ОккамВ этой главе описывается понятие производного класса в С ++. Производные классы дают простой, гибкий и эффективный апарат задания для класса альтернативного интерфейса и опредления класса посредством добавления возможностей к уже имещемуся классу без перепрограммирования или перекомпиляции. С помощью производных классов можно также обеспечить общий итерфейс для нескольких различных классов так, чтобы другие части программы могли работать с объектами этих классов однаковым образом. При этом обычно в каждый объект помещается информация о типе, чтобы эти объекты могли обрабатываться сответствующим образом в ситуациях, когда их тип нельзя узнать во время компиляции. Для элегантной и надежной обработки тких динамических зависимостей типов имеется понятие виртуалной функции. По своей сути производные классы существуют для того, чтобы облегчить программисту формулировку общности.
7.1 Введение
Представим себе процесс написания некоторого универсалного средства (например, тип связанный список, таблица имен или планировщик для системы моделирования), которое преднаначается для использования многими разными людьми в различных обстоятельствах. Очевидно, что в кандидатах на роль таких средств недостатка нет, и выгоды от их стандартизации огроны. Кажется, любой опытный программист написал (и отладил) дюжину вариантов типов множества, таблицы имен, сортирующей функции и т.п., но оказывается, что каждый программист и кадая программа используют свою версию этих понятий, из-за чего программы слишком трудно читать, тяжело отлаживать и сложно модифицировать. Более того, в большой программе вполне может быть несколько копий идентичных (почти) частей кода для рабты с такими фундаментальными понятиями.
Причина этого хаоса частично состоит в том, что предствить такие общие понятия в языке программирования сложно с концептуальной точки зрения, а частично в том, что средства, обладающие достаточной общностью, налагают дополнительные расходы по памяти и/или по времени, что делает их неудобными для самых простых и наиболее напряженно используемых средств (связанные списки, вектора и т.п.), где они были бы наиболее полезны. Понятие производного класса в С++, описываемое в #7.2, не обеспечивают общего решения всех этих проблем, но оно дает способ справляться с довольно небольшим числом ваных случаев. Будет, например, показано, как определить эффетивный класс обобщенного связанного списка таким образом, чтобы все его версии разделяли код.
Написание общецелевых средств – задача непростая, и чато основной акцент в их разработке другой, чем при разработке программ специального назначения. Конечно, нет четкой границы между средствами общего и специального назначения, и к метдам и языковым средствам, которые описываются в этой главе, можно относиться так, что они становятся все более полезны с ростом объема и сложности создаваемых программ.
7.2 Производные классы
Чтобы разделить задачи понимания аппарата языка и метдов его применения, знакомство с понятием производных классов делается в три этапа. Вначале с помощью небольших примеров, которые не надо воспринимать как реалистичные, будут описаны
сами средства языка (запись и семантика). После этого демонтрируются некоторые неочевидные применения производных класов, и, наконец, приводится законченная программа.
7.2.1 Построение производного класса
Рассмотрим построение программы, которая имеет дело с людьми, служащими в некоторой фирме. Структура данных в этой программе может быть например такой:
struct employee (* // служащий char* name; // имя short age; // возраст short department; // подразделение int salary; // жалование employee* next; // ... *);
Список аналогичных служащих будет связываться через поле next. Теперь давайте определим менеджера:
struct manager (* // менеджер employee emp; // запись о менеджере как о служащем employee* group; // подчиненные люди // ... *);
Менеджер также является служащим; относящиеся к служащму employee данные хранятся в члене emp объекта manager. Для читающего это человека это, может быть, очевидно, но нет нчего выделяющего член emp для компилятора. Указатель на мнеджера (manager*) не является указателем на служащего (employee*), поэтому просто использовать один там, где требется другой, нельзя. В частности, нельзя поместить менеджера в список служащих, не написав для этого специальный код. Моно либо применить к manager* явное преобразование типа, либо поместить в список служащих адрес члена emp, но и то и другое мало элегантно и довольно неясно. Корректный подход состоит в том, чтобы установить, что менеджер является служащим с некторой добавочной информацией: