Чтение онлайн

на главную - закладки

Жанры

Шрифт:

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; // подчиненные люди // ... *);

Поделиться:
Популярные книги

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

Я сделаю это сама

Кальк Салма
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Я сделаю это сама

Газлайтер. Том 18

Володин Григорий Григорьевич
18. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 18

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Новый Рал 9

Северный Лис
9. Рал!
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Новый Рал 9

Право на месть

Ледова Анна
3. Академия Ровельхейм
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Право на месть

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Сумеречный Стрелок 4

Карелин Сергей Витальевич
4. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 4

Кровь на эполетах

Дроздов Анатолий Федорович
3. Штуцер и тесак
Фантастика:
альтернативная история
7.60
рейтинг книги
Кровь на эполетах

Ржевский 6

Афанасьев Семён
6. Ржевский
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Ржевский 6

Любовь Носорога

Зайцева Мария
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Любовь Носорога

Черный Маг Императора 7 (CИ)

Герда Александр
7. Черный маг императора
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 7 (CИ)

Хозяйка покинутой усадьбы

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка покинутой усадьбы