ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 9) онлайн
Упражнения
Решения к упражнениям, помеченным знаком *, можно найти в приложении Ж. *1. Представьте себе издательскую компанию, которая торгует книгами и аудио-записями этих книг. Создайте класс publication, в котором хранятся название (строка) и цена (типа float) книги. От этого класса наследуются еще два класса: book, который содержит информацию о количестве страниц в книге (типа int), и type, который содержит время записи книги в минутах (тип float). В каждом из этих трех классов должен быть метод getdata(), через который можно получать данные от пользователя с клавиатуры, и putdata(), предназначенный для вывода этих данных.
Напишите функцию main() программы для проверки классов book и type. Создайте их объекты в программе и запросите пользователя ввести и вы- вести данные с использованием методов getdata() и putdata(). *2. Вспомните пример STRCONV из главы 8. Класс String в этом примере имеет дефект: у него нет защиты на тот случай, если его объекты будут инициа- лизированы слишком длинной строкой (константа SZ имеет значение 80). Например, определение
String s = "Эта строка имеет очень большую длину и мы можем быть уверены, что она не уместится в отведенный буфер, что приведет к непредсказуемым последствиям.";
будет причиной переполнения массива str строкой s с непредсказуемыми последствиями вплоть до краха системы.
Создадим класс Pstring, производный от класса String, в котором предот- вратим возможность переполнения буфера при определении слишком длинной строковой константы. Новый конструктор производного класса будет копировать в str только SZ-1 символов, если строка окажется слиш- ком длинной, и будет копировать строку полностью, если она будет иметь длину меньшую, чем SZ. Напишите функцию main() программы для про- верки ее работы со строками разной длины.
*3. Начните с классов book, type и publication из упражнения 1. Добавьте базо- вый класс sales, в котором содержится массив, состоящий из трех значе- ний типа float, куда можно записать общую стоимость проданных книг за последние три месяца. Включите в класс методы getdata() для получения значений стоимости от пользователя и putdata() для вывода этих цифр. Измените классы book и type так, чтобы они стали производными обоих классов: publications и sales. Объекты классов book и type должны вводить и выводить данные о продажах вместе с другими своими данными. Напи- шите функцию main() для создания объектов классов book и type, чтобы протестировать возможности ввода/вывода данных.
4. Предположим, что издатель из упражнений 1 и 3 решил добавить к своей продукции версии книг на компьютерных дисках для тех, кто любит чи- тать книги на своих компьютерах. Добавьте класс disk, который, как book и type, является производным класса publication. Класс disk должен вклю- чать в себя те же функции, что и в других классах. Полем только этого класса будет тип диска: CD или DVD. Для хранения этих данных вы мо- жете ввести тип enum. Пользователь должен выбрать подходящий тип, на- брав на клавиатуре с или d.
5. Создайте производный класс employee2 от базового класса employee из программы EMPLOY этой главы. Добавьте в новый класс поле compensation типа double и поле period типа enum для обозначения периода оплаты ра- боты служащего: почасовая, понедельная или помесячная. Для простоты вы можете изменить классы laborer, manager и scientist так, чтобы они ста- ли производными нового класса employee2. Однако заметим, что во мно- гих случаях создание отдельного класса compensation и трех его производ- ных классов manager2, scientist2 и laborer2 более соответствовало бы духу ООП. Затем можно применить множественное наследование и сделать так, чтобы эти три новых класса стали производными класса compensation и первоначальных классов manager, scientist и laborer. Таким путем можно избежать модификации исходных классов.
6. Вспомним программу ARROVER3 из главы 8. Сохраним класс safearray таким же и, используя наследование, добавим к нему возможность для пользо- вателя определять верхнюю и нижнюю границы массива в конструкторе. Это похоже на упражнение 9 из главы 8, за исключением того, что при- менено наследование для создания нового класса (можно назвать его safehilo) взамен модификации исходного класса.
7. Вспомним программу COUNTEN2 из этой главы. В ней можно увеличивать и уменьшать счетчик, используя префиксные операции. Используя насле- дование, добавьте возможность использования постфиксных операций для случаев увеличения и уменьшения. (Описание постфиксных операций вы сможете найти в главе 8.)
8. В некоторых компьютерных языках, таких, как Visual Basic, есть опера- ции, с помощью которых можно выделить часть строки и присвоить ее другой строке. (В стандартном классе string предложены различные под-
ходы.) Используя наследование, добавьте такую возможность в класс Pstring из упражнения 2. В новом производном классе Pstring2 разместите три новых функции: left(), mid() и right().
s2.left ( s1, n ) // в строку s2 помещаются n самых левых
// символов строки s1 s2.mid ( s1, s, n ) // в строку s2 помещаются n символов из строки
// начиная с символа номер s s2.right ( s1, n ) // в строку s2 помещаются n самых правых // символов строки s1
Вы можете использовать цикл for для копирования символ за символом подходящих частей строки s1 во временный объект класса Pstring2, кото- рый затем их возвратит. Для получения лучшего результата используйте в этих функциях возврат по ссылке, чтобы они могли быть использованы с левой стороны знака «равно» для изменения части существующей строки.
9. Вспомним классы publication, book и type из упражнения 1. Предположим, что мы хотим добавить в классы book и type дату выхода книги. Создайте новый производный класс publication2, который является производным класса publication и включает в себя поле, хранящее эту дату. Затем из- мените классы book и type так, чтобы они стали производными класса publication2 вместо publication. Сделайте необходимые изменения функций классов так, чтобы пользователь мог вводить и выводить дату выхода книги. Для даты можно использовать класс data из упражнения 5 главы 6, который хранит дату в виде трех целых: для месяца, для дня и для года.
10. В программе EMPMULT этой главы существует только один тип должно- сти менеджера. В любой серьезной компании кроме менеджеров сущест- вуют еще и управляющие. Создадим производный от класса manager класс executive. (Мы предполагаем, что управляющий — это главный менеджер.) Добавочными данными этого класса будут размер годовой премии и ко- личество его акций в компании. Добавьте подходящие методы для этих данных, позволяющие их вводить и выводить.
11. В различных ситуациях иногда требуется работать с двумя числами, объ- единенными в блок. Например, каждая из координат экрана имеет гори- зонтальную составляющую (x) и вертикальную (y). Представьте такой блок чисел в качестве структуры pair, которая содержит две переменные типа int. Теперь предположим, что мы хотим иметь возможность хранить перемен- ные типа pair в стеке. То есть мы хотим иметь возможность положить пе- ременную типа pair в стек путем вызова метода push() с переменной типа pair в качестве аргумента и вынуть ее из стека путем вызова метода pop(), возвращающего переменную типа pair. Начнем с класса Stack2 программы STAKEN из этой главы. Создадим производный от него класс pairStack. В нем будут содержаться два метода: перегружаемый метод push() и перегру- жаемый метод pop(). Метод pairStack::push() должен будет сделать два вы- зова метода Stack2::push(), чтобы сохранить оба числа из пары, а метод pairStack::pop() должен будет сделать два вызова метода Stack2::pop().
12. Рассмотрим старую Британскую платежную систему фунты-стерлинги- пенсы (см. упражнение 10 главы 4 «Структуры»). Пенни в дальнейшем делятся на фартинги и полупенни. Фартинг — это 1/4 пенни. Существо- вали монеты фартинг, полфартинга и пенни. Любые сочетания монет вы- ражались через восьмые части пенни:
1/8 пенни — это полфартинга;
1/4 пенни — это фартинг;
3/8 пенни — это фартинг с половиной;
1/2 пенни — это по\nенни;
5/8 пенни — это полфартинга плюс по\nенни;
3/4 пенни — это по\nенни плюс фартинг;
7/8 пенни — это по\nенни плюс фартинг с половиной.
Давайте предположим, что мы хотим добавить в класс sterling возмож- ность пользоваться этими дробными частями пенни. Формат ввода/выво- да может быть похожим на £1.1.1-1/4 или £9.19.11-7/8, где дефисы отде- ляют дробные части от пенни.
Создайте новый класс sterfrac, производный от класса sterling. В нем долж- на быть возможность выполнения четырех основных арифметических опе- раций со стерлингами, включая восьмые части пенни. Поле eighths типа int определяет количество восьмых. Вам нужно будет перегрузить методы класса sterling, чтобы они могли работать с восьмыми частями. Пользова- тель должен иметь возможность ввести и вывести дробные части пенни. Не обязательно использовать класс fraction полностью (см. упражнение 11 главы 6), по вы можете это сделать для большей точности.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42