ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В 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), по вы можете это сделать для большей точности.

 

 

42