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

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

Жанры

Шрифт:

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

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

Повседневная жизнь в эпоху Жанны д'Арк

Дефурно Марселен
Живая история: Повседневная жизнь человечества
Научно-образовательная:
история
культурология
5.00
рейтинг книги
Повседневная жизнь в эпоху Жанны д'Арк

Учитель истории

Ибрагимов Канта
Проза:
военная проза
историческая проза
4.00
рейтинг книги
Учитель истории

Учитель из прошлого тысячелетия

Еслер Андрей
6. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Учитель из прошлого тысячелетия

Swvswh40k

Кросскун / Krosskun
5.00
рейтинг книги
Swvswh40k

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.25
рейтинг книги
Враг из прошлого тысячелетия

Путь, исполненный отваги. Задолго до Истмата

Беразинский Дмитрий Вячеславович
Фантастика:
научная фантастика
7.62
рейтинг книги
Путь, исполненный отваги. Задолго до Истмата

Семиотические исследования

Розин Вадим Маркович
Humanitas
Научно-образовательная:
философия
5.00
рейтинг книги
Семиотические исследования

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Ваше Сиятельство

Первый среди равных. Книга III

Бор Жорж
3. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
6.00
рейтинг книги
Первый среди равных. Книга III

Я иду искать. История третья и четвертая

Верещагин Олег Николаевич
3. Я иду искать
Фантастика:
боевая фантастика
6.25
рейтинг книги
Я иду искать. История третья и четвертая

Антракт. Поминки. Жизнеописание. Шатало

Эдлис Юлиу
5.00
рейтинг книги
Антракт. Поминки. Жизнеописание. Шатало

Инженер Петра Великого 3

Гросов Виктор
3. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Инженер Петра Великого 3

Большой шеф Красной капеллы: Впервые в мире беседы с Леопольдом Треппером

Томин Валентин Романович
Герои тайной войны
Приключения:
исторические приключения
5.00
рейтинг книги
Большой шеф Красной капеллы: Впервые в мире беседы с Леопольдом Треппером

1876

Видал Гор
3. История империи
Проза:
проза прочее
5.00
рейтинг книги
1876