ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 6) онлайн

Упражнения

Решения к упражнениям, помеченным знаком *, можно найти в приложении Ж. *1.         Создайте класс Int, имитирующий стандартный тип int. Единственное                 поле этого класса должно иметь тип int. Создайте методы, которые будут                 устанавливать значение поля, равным нулю, инициализировать его целым                 значением, выводить значение поля на экран и складывать два значения                 типа Int.

Напишите программу, в которой будут созданы три объекта класса Int, два из которых будут инициализированы. Сложите два инициализирован- ных объекта, присвойте результат третьему, а затем отобразите результат на экране.

*2. Представьте пункт для взимания платежей за проезд по автостраде. Каж- дая проезжающая машина должна заплатить за проезд 50 центов, однако часть машин платит за проезд, а часть проезжает бесплатно. В кассе ведет- ся учет числа проехавших машин и суммарная выручка от платы за проезд.

Создайте модель такой кассы с помощью класса tollBooth. Класс должен содержать два поля. Одно из них, типа unsigned int, предназначено для учета количества проехавших автомобилей, а второе, имеющее тип double, будет содержать суммарную выручку от оплаты проезда. Конструктор дол- жен инициализировать оба поля нулевыми значениями. Метод payingCar() инкрементирует число машин и увеличивает на 0,50 суммарную выручку. Другой метод, nopayCar(), увеличивает на единицу число автомобилей, но оставляет без изменения выручку. Метод display() выводит оба значения на экран. Там, где это возможно, сделайте методы константными.

Создайте программу, которая продемонстрирует работу класса. Програм- ма должна предложить пользователю нажать одну клавишу для того, что- бы сымитировать заплатившего автолюбителя, и другую клавишу, чтобы сымитировать недобросовестного водителя. Нажатие клавиши Esc должно привести к выдаче текущих значений количества машин и выручки и за- вершению программы.

*3. Создайте класс с именем time, содержащий три поля типа int, предназна- ченные для хранения часов, минут и секунд. Один из конструкторов клас- са должен инициализировать поля нулевыми значениями, а другой конст- руктор — заданным набором значений. Создайте метод класса, который будет выводить значения полей на экран в формате 11:59:59, и метод, складывающий значения двух объектов типа time, передаваемых в качест- ве аргументов.

В функции main() следует создать два инициализированных объекта (по- думайте, должны ли они быть константными) и один неинициализиро- ванный объект. Затем сложите два инициализированных значения, а ре- зультат присвойте третьему объекту и выведите его значение на экран. Где возможно, сделайте методы константными.

4.       Создайте класс employee, используя упражнение 4 главы 4. Класс должен включать поле типа int для хранения номера сотрудника и поле типа float для хранения величины его оклада. Методы класса должны позволять пользователю вводить и отображать данные класса. Напишите функцию main(), которая запросит пользователя ввести данные для трех сотрудни- ков и выведет полученную информацию на экран.

5. Взяв в качестве основы структуру из упражнения 5 главы 4, создайте класс date. Его данные должны размещаться в трех полях типа int: month, day и year. Метод класса getdate() должен принимать значение для объекта в формате 12/31/02, а метод showdate() — выводить данные на экран.

6. Расширьте содержание класса employee из упражнения 4, включив в него класс date и перечисление etype (см. упражнение 6 главы 4). Объект клас- са date будет использоваться для хранения даты приема сотрудника на ра- боту. Перечисление будет использовано для хранения статуса сотрудника: лаборант, секретарь, менеджер и т. д. Последние два поля данных должны быть закрытыми в определении класса employee, как и номер и оклад сотруд- ника. Вам будет необходимо разработать методы getemploy() и putemploy(), предназначенные соответственно для ввода и отображения информации о сотруднике. Возможно, при создании методов вам понадобится ветвление switch для работы с перечисляемым типом etype. Напишите функцию main(), которая попросит пользователя ввести данные о трех сотрудниках, а за- тем выведет эти данные на экран.

7. В морской навигации координаты точки измеряются в градусах и мину- тах широты и долготы. Например, координаты бухты Папити на о. Таити равны 149 градусов 34.8 минут восточной долготы и 17 градусов 31.5 ми- нут южной широты. Это записывается как 149°34.8' W, 17°31.5' S. Один градус равен 60 минутам (устаревшая система также делила одну минуту на 60 секунд, но сейчас минуту делят на обычные десятичные доли). Дол- гота измеряется величиной от 0 до 180 градусов восточнее или западнее Гринвича. Широта принимает значения от 0 до 90 градусов севернее или южнее экватора.

8. Создайте класс angle, включающий следующие три поля: типа int для чис- ла градусов, типа float для числа минут и типа char для указания направ- ления (N, S, Е или W). Объект этого класса может содержать значение как широты, так и долготы. Создайте метод, позволяющий ввести коорди- нату точки, направление, в котором она измеряется, и метод, выводящий на экран значение этой координаты, например 179°59.9' Е. Кроме того, напишите конструктор, принимающий три аргумента. Напишите функцию main(), которая сначала создает переменную с помощью трехаргументного конструктора и выводит ее значение на экран, а затем циклически запра- шивает пользователя ввести значение координаты и отображает введен- ное значение на экране. Для вывода символа градусов (°) можно восполь- зоваться символьной константой '\xF8'.

Создайте класс, одно из полей которого хранит «порядковый номер» объ- екта, то есть для первого созданного объекта значение этого поля равно 1, для второго созданного объекта значение равно 2 и т. д.

Для того чтобы создать такое поле, вам необходимо иметь еще одно поле, в которое будет записываться количество созданных объектов класса (это означает, что последнее поле должно относиться не к отдельным объек- там класса, а ко всему классу в целом. Вспомните, какое ключевое слово необходимо при описании такого поля.). Каждый раз при создании ново- го объекта конструктор может получить значение этого поля и в соответ- ствии с ним назначить объекту индивидуальный порядковый номер.

В класс следует включить метод, который будет выводить на экран по- рядковый номер объекта. Создайте функцию main(), в которой будут соз- даны три объекта, и каждый объект выведет на экран свой порядковый номер, например: Мой порядковый номер: 2 и т. п.

9. На основе структуры fraction из упражнения 8 главы 4 создайте класс fraction. Данные класса должны быть представлены двумя полями: числи- телем и знаменателем. Методы класса должны получать от пользователя значения числителя и знаменателя дроби в форме 3/5 и выводить значе- ние дроби в этом же формате. Кроме того, должен быть разработан метод, складывающий значения двух дробей. Напишите функцию main(), которая циклически запрашивает у пользователя ввод пары дробей, затем склады- вает их и выводит результат на экран. После каждой такой операции про- грамма должна спрашивать пользователя, следует ли продолжать цикл.

10. Создайте класс с именем ship, который будет содержать данные об учет- ном номере корабля и координатах его расположения. Для задания номера корабля следует использовать механизм, аналогичный описанному в уп- ражнении 8. Для хранения координат используйте два поля типа angle (см. упражнение 7). Разработайте метод, который будет сохранять в объек- те данные о корабле, вводимые пользователем, и метод, выводящий данные о корабле на экран. Напишите функцию main(), создающую три объекта класса ship, затем запрашивающую ввод пользователем информации о каж- дом из кораблей и выводящую на экран всю полученную информацию.

11. Модифицируйте калькулятор, созданный в упражнении 12 главы 5 так, чтобы вместо структуры fraction использовался одноименный класс. Класс должен содержать методы для ввода и вывода данных объектов, а также для выполнения арифметических операций. Кроме того, необходимо вклю- чить в состав класса функцию, приводящую дробь к несократимому виду. Функция должна находить наибольший общий делитель числителя и зна- менателя и делить числитель и знаменатель на это значение. Код функ- ции, названной lowterms(), приведен ниже:

void fraction::lowterms()    // сокращение дроби

{

long tnum, tden, temp, gcd;

tnum = labs(num);            // используем неотрицательные

tden = labs(den);            // значения (нужен cmath)

if( tden == 0 )              // проверка знаменателя на 0

  { cout << "Недопустимый знаменатель!"; exit(1); }

else if( tnum == 0 )         // проверка числителя на 0

  { num=0; den = 1; return; }

// нахождение наибольшего общего делителя

while(tnum !=0)

{

  if( tnum < tden )          // если числитель больше знаменателя,

    { temp=tnum; tnum=tden; tden=temp; } //меняем их местами

  tnum = tnum - tden;        // вычитание

}

gcd = tden;                  // делим числитель и знаменатель на

num = num / gcd;             // полученный наибольший общий делитель

den = den / gcd;

}

Можно вызывать данную функцию в конце каждого метода, выполня- ющего арифметическую операцию, либо непосредственно перед выводом на экран результата. Кроме перечисленных методов, вы можете вклю- чить в класс конструктор с двумя аргументами, что также будет полезно.

12. Используйте преимущество ООП, заключающееся в том, что однажды созданный класс можно помещать в другие программы. Создайте новую программу, которая будет включать класс fraction, созданный в упраж- нении 11. Программа должна выводить аналог целочисленной таблицы умножения для дробей. Пользователь вводит знаменатель, а программа должна подобрать всевозможные целые значения числителя так, чтобы значения получаемых дробей находились между 0 и 1. Дроби из получив- шегося таким образом набора перемножаются друг с другом во всевоз- можных комбинациях, в результате чего получается таблица следующего вида (для знаменателя, равного 6):

                               1/6    1/3    1/2    2/3   5/6

                -----------------------------------------

                1/6   1/36   1/18   1/12   1/9   5/36

                1/3   1/18   1/9    1/6    2/9   5/18

                1/2   1/12   1/6    1/4    1/3   5/12

                2/3   1/9    2/9    1/3    4/9   5/9

                5/6   5/36   5/18   5/12   5/9   25/36

 

 

32