*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. Пользователь должен выбрать подходящий тип, на-
брав на клавиаtype с или d.
5. Создайте производный класс employee2 от базового класса employee из
программы EMPLOY этой главы. Добавьте в новый класс поле compensation
типа double и поле period типа enum для обозначения периода оплаты ра-
боты служащего: почасовая, понедельная или помесячная. Для простоты
вы можете изменить классы laborer, manager и scientist так, чтобы они ста-
ли производными нового класса employee2. Однако заметим, что во мно-
гих случаях создание отдельного класса compensation и трех его производ-
ных классов manager2, scientist2 и laborer2 более соответствовало бы духу
ООП. Затем можно применить множественное наследование и сделать
так, чтобы эти три новых класса стали производными класса compensation
и первоначальных классов manager, scientist и laborer. Таким путем можно
избежать модификации исходных классов.
6. Вспомним программу ARROVER3 из главы 8. Сохраним класс safearay таким
же и, используя наследование, добавим к нему возможность для пользо-
вателя определять верхнюю и нижнюю границы массива в конструкторе.
Это похоже на упражнение 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 пенни — это по\пенни ;
5/8 пенни — это полфартинга плюс по\пенни ;
3/4 пенни — это по\пенни плюс фартинг;
7/8 пенни — это по\пенни плюс фартинг с половиной.
Давайте предположим, что мы хотим добавить в класс sterling возмож-
ность пользоваться этими дробными частями пенни. Формат ввода/выво-
да может быть похожим на £1.1.1-1/4 или £9.19.11-7/8, где дефисы отде-
ляют дробные части от пенни.
Создайте новый класс sterfrac, производный от класса sterling. В нем долж-
на быть возможность выполнения четырех основных арифметических опе-
раций со стерлингами, включая восьмые части пенни. Поле eighths типа
int определяет количество восьмых. Вам нужно будет перегрузить методы
класса sterling, чтобы они могли работать с восьмыми частями. Пользова-
тель должен иметь возможность ввести и вывести дробные части пенни.
Не обязательно использовать класс fraction полностью (см. упражнение 11
главы 6), по вы можете это сделать для большей точности.
1)
#include "stdafx.h"
#include<iostream>
#include <string>
using namespace std;
///////////////////////////////////////////////////////
class Publication
{
private:
char name [80];
float price;
public:
void getdata()
{
cout << "Enter the name of book: "; cin >> name;
cout << "\nPrice:"; cin >> price;
}
void putdata()const
{
cout << "\n" << name << "\n" << price;
}
};
////////////////////////////////////////////////////////
class Book : private Publication
{
private:
int pages;
public:
void getgata()
{
Publication::getdata();
cout << "\npage by the number of the book: "; cin >> pages;
}
void putdata()const
{
Publication::putdata();
cout << "\n" << pages;
}
};
//////////////////////////////////////////////////////////
class Type : private Publication
{
private:
float time;
public:
void getdata()
{
Publication::getdata();
cout << "\nthe recording of the book: "; cin >> time;
}
void putdata()const
{
Publication::putdata();
cout << "\n" << time;
}
};
////////////////////////////////////////////////////////////
int main()
{
Book bok;
Type tp;
bok.getgata();
tp.getdata();
cout << "\n" << "class Book: ";
bok.putdata();
cout << "\n" << "class Type: ";
tp.putdata();
cout << endl;
system ("pause");
};
3)
#include "stdafx.h"
#include<iostream>
#include <string>
using namespace std;
///////////////////////////////////////////////////////
const int SAL = 3;
class Sales
{
private:
float sales [SAL];
public:
void getdata()
{
for (int j = 1; j <= SAL; j++)
{
cout << "\nThe total value of books sold in the " << j << " month: ";
cin >> sales[j];
}
}
void putdata()const
{
for (int j = 1; j <= SAL; j++)
{
cout << "\nThe total value of books sold in the " << j << " month: ";
cout << sales[j];
}
}
};
//////////////////////////////////////////////////////////////
class Publication
{
private:
string name;
float price;
public:
Publication() : price(0)
{}
void getdata()
{
cout << "Enter the name of book: "; cin >> name;
cout << "\nPrice: "; cin >> price;
}
void putdata()const
{
cout << "\nname of book: " << name << "\nPrice: " << price;
}
};
////////////////////////////////////////////////////////
class Book : private Sales, private Publication
{
private:
int pages;
public:
Book () : pages(0)
{}
void getgata()
{
Publication::getdata();
cout << "\npage by the number of the book: "; cin >> pages;
Sales::getdata();
}
void putdata()const
{
Publication::putdata();
cout << "\npage by the number of the book: " << pages;
Sales::putdata();
}
};
//////////////////////////////////////////////////////////
class Type : private Sales, private Publication
{
private:
float time;
public:
Type() : time(0)
{}
void getdata()
{
Publication::getdata();
cout << "\nthe recording of the book: "; cin >> time;
Sales::getdata();
}
void putdata()const
{
Publication::putdata();
cout << "\nthe recording of the book: " << time;
Sales::putdata();
}
};
////////////////////////////////////////////////////////////
int main()
{
Book bok;
Type tp;
bok.getgata();
tp.getdata();
cout << "\n" << "class Book: ";
bok.putdata();
cout << "\n" << "class Type: ";
tp.putdata();
cout << endl;
system ("pause");};
4)
#include "stdafx.h"
#include<iostream>
#include <string>
using namespace std;
///////////////////////////////////////////////////////
const int SAL = 3;
class Sales
{
private:
float sales [SAL];
public:
void getdata()
{
for (int j = 1; j <= SAL; j++)
{
cout << "\nThe total value of books sold in the " << j << " month: ";
cin >> sales[j];
}
}
void putdata()const
{
for (int j = 1; j <= SAL; j++)
{
cout << "\nThe total value of books sold in the " << j << " month: ";
cout << sales[j];
}
}
};
//////////////////////////////////////////////////////////////
class Publication
{
private:
string name;
float price;
public:
void getdata()
{
cout << "Enter the name of book: "; cin >> name;
cout << "\nPrice: "; cin >> price;
}
void putdata()const
{
cout << "\nname of book: " << name << "\nPrice: " << price;
}
};
////////////////////////////////////////////////////////
class Book : private Sales, private Publication
{
private:
int pages;
public:
void getgata()
{
Publication::getdata();
cout << "\npage by the number of the book: "; cin >> pages;
Sales::getdata();
}
void putdata()const
{
Publication::putdata();
cout << "\npage by the number of the book: " << pages;
Sales::putdata();
}
};
//////////////////////////////////////////////////////////
class Type : private Sales, private Publication
{
private:
float time;
public:
void getdata()
{
Publication::getdata();
cout << "\nthe recording of the book: "; cin >> time;
Sales::getdata();
}
void putdata()const
{
Publication::putdata();
cout << "\nthe recording of the book: " << time;
Sales::putdata();
}
};
////////////////////////////////////////////////////////////
class Disk : private Sales, private Publication
{
private:
enum etype {CD, DVD};
public:
void getdata()
{
etype t_disk;
char type;
Publication::getdata();
cout << "\nDisc type (c/d): "; cin >> type;
if (type = 'c')
t_disk = CD;
else t_disk = DVD;
Sales::getdata();
}
void putdata()const
{
Publication::putdata();
etype t_disk;
char type;
cout << "\nDisc type: ";
if (t_disk = CD)
cout << "CD";
else
cout << "DVD";
Sales::putdata();
}
};
//////////////////////////////////////////////////////////
int main()
{
Book bok;
Type tp;
Disk dk;
bok.getgata();
tp.getdata();
dk.getdata();
cout << "\n" << "class Book: ";
bok.putdata();
cout << "\n" << "class Type: ";
tp.putdata();
cout << "\n" << "class Disk: ";
dk.putdata();
cout << endl;
system ("pause");
};
5)
#include "stdafx.h"
#include <iostream>
using namespace std;
const int LEN = 80; // максимальная длина имени
///////////////////////////////////////////////////////////
class employee // некий сотрудник
{
private:
char name[LEN]; // имя сотрудника
unsigned long number; // номер сотрудника
public:
void getdata()
{
cout << "\n Введите фамилию: "; cin >> name;
cout << " Введите номер: "; cin >> number;
}
void putdata() const
{
cout << "\n Фамилия: " << name;
cout << "\n Номер: " << number;
}
};
///////////////////////////////////////////////////////////
class employee2 : public employee
{
private:
double compensations;
enum etype {hourly, weekly, monthly};
etype period;
public:
void getdata()
{
employee::getdata();
char type;
cout << "\n Введите компенсацию: "; cin >> compensations;
cout << "\n Введите период оплаты работы (первую букву от hourly, weekly, monthly): "; cin >> type;
switch (type)
{
case 'h':
period = hourly; break;
case 'w':
period = weekly; break;
case 'm':
period = monthly; break;
}
}
void putdata()const
{
employee::putdata();
cout << "\n компенсация: " << compensations;
cout << "\n Период оплаты работы : ";
switch (period)
{
case hourly:
cout << "почасово"; break;
case weekly:
cout << "понедельно"; break;
case monthly:
cout << "помесячно"; break;
}
}
};
//////////////////////////////////////////////////////////
class manager : public employee2 // менеджер
{
private:
char title[LEN]; // должность, например вице-президент
double dues; // сумма взносов в гольф-клуб
public:
void getdata()
{
employee2::getdata();
cout << " Введите должность: "; cin >> title;
cout << " Введите сумму взносов в гольф-клуб: "; cin >> dues;
}
void putdata() const
{
employee2::putdata();
cout << "\n Должность: " << title;
cout << "\n Сумма взносов в гольф-клуб: " << dues;
}
};
///////////////////////////////////////////////////////////
class scientist : public employee2 // ученый
{
private:
int pubs; // количество публикаций
public:
void getdata()
{
employee2::getdata();
cout << " Введите количество публикаций: "; cin >> pubs;
}
void putdata() const
{
employee2::putdata();
cout << "\n Количество публикаций: " << pubs;
}
};
///////////////////////////////////////////////////////////
class laborer : public employee2 // рабочий
{
};
///////////////////////////////////////////////////////////
int main()
{
setlocale (0, "");
manager m1, m2;
scientist s1;
laborer l1;
cout << endl;
cout << "\nВвод информации о первом менеджере";
m1.getdata();
cout << "\nВвод информации о втором менеджере";
m2.getdata();
cout << "\nВвод информации о первом ученом";
s1.getdata();
cout << "\nВвод информации о первом рабочем";
l1.getdata();
cout << "\nИнформация о первом менеджере";
m1.putdata();
cout << "\nИнформация о втором менеджере";
m2.putdata();
cout << "\nИнформация о первом ученом";
s1.putdata();
cout << "\nИнформация о первом рабочем";
l1.putdata();
cout << endl;
system("pause");
return 0;
}
#include "stdafx.h"
#include <iostream>
using namespace std;
///////////////////////////////////////////////////////////
class Counter
{
protected: // заметьте, что тут не следует использовать private
int count; // счетчик
public:
Counter() : count(0) // конструктор без параметров
{ }
Counter(int c) : count(c) // конструктор с одним параметром
{ }
unsigned int get_count() const // получение значения
{
return count;
}
Counter operator++() // оператор увеличения
{
return Counter(++count);
}
};
///////////////////////////////////////////////////////////
class CountDn : public Counter
{
public:
CountDn() : Counter() // конструктор без параметров
{ }
CountDn(int c) : Counter(c) // конструктор с одним параметром
{ }
CountDn operator--() // оператор уменьшения
{
return CountDn(--count);
}
};
class Postfix : public CountDn
{
public:
Postfix() : CountDn()
{}
Postfix(int c) : CountDn(c)
{}
Postfix operator++(int)
{
return Postfix(count++);
}
Postfix operator--(int)
{
return Postfix(count--);
}
};
///////////////////////////////////////////////////////////
int main()
{
Counter* c1 = new Postfix;
cout << "\nc1 = " << c1->get_count();
++*c1; ++*c1; ++*c1;
cout << "\nc1 = " << c1->get_count();
CountDn* c2 = new Postfix;
cout << "\nc2 = " << c2->get_count();
--*c2; --*c2; --*c2;
cout << "\nc2 = " << c2->get_count();
Postfix c3, c4(10);
c3 = c4++;
c3.get_count();
c3 = c4++;
c3.get_count();
cout << endl;
cin.get();
return 0;
}
9)
#include "stdafx.h"
#include<iostream>
#include <string>
using namespace std;
///////////////////////////////////////////////////////
class Publication
{
private:
char name [80];
float price;
public:
void getdata()
{
cout << "Enter the name of book: "; cin >> name;
cout << "\nPrice:"; cin >> price;
}
void putdata()const
{
cout << "\n the name of book: " << name << "\n Price: " << price;
}
};
////////////////////////////////////////////////////////
class Publication2 : public Publication
{
private:
int day, month, year;
public:
Publication2() : month(0), day(0), year(0)
{}
Publication2(int d, int m, int y) : month(m), day(d), year(y)
{}
void getdata()
{
Publication::getdata();
char ch;
cout << "\nenter day, month and year (XX/XX/XXXX) " << endl;
cin >> day >> ch >> month >> ch >> year;
}
void putdata()const
{
Publication::putdata();
char ch = '/';
cout << "\n date publication: " << day << ch << month << ch << year << endl;
}
};
////////////////////////////////////////////////////////
class Book : private Publication2
{
private:
int pages;
public:
void getgata()
{
Publication2::getdata();
cout << "\npage by the number of the book: "; cin >> pages;
}
void putdata()const
{
Publication2::putdata();
cout << "\n page by the number of the book: " << pages;
}
};
//////////////////////////////////////////////////////////
class Type : private Publication2
{
private:
float time;
public:
void getdata()
{
Publication2::getdata();
cout << "\n the recording of the book: "; cin >> time;
}
void putdata()const
{
Publication2::putdata();
cout << "\n the recording of the book: " << time;
}
};
////////////////////////////////////////////////////////////
int main()
{
Book bok;
Type tp;
bok.getgata();
tp.getdata();
cout << "\n" << "class Book: ";
bok.putdata();
cout << "\n" << "class Type: ";
tp.putdata();
cout << endl;
system ("pause");
};
10)
#include "stdafx.h"
#include <iostream>
using namespace std;
const int LEN = 80; // максимальная длина имени
///////////////////////////////////////////////////////////
class student // сведения об образовании
{
private:
char school[LEN]; // название учебного заведения
char degree[LEN]; // уровень образования
public:
void getedu()
{
cout << " Введите название учебного заведения: ";
cin >> school;
cout << " Введите степень высшего образования\n";
cout << " (неполное высшее, бакалавр, магистр, кандидат наук): ";
cin >> degree;
}
void putedu() const
{
cout << "\n Учебное заведение: " << school;
cout << "\n Степень: " << degree;
}
};
///////////////////////////////////////////////////////////
class employee // некий сотрудник
{
private:
char name[LEN]; // имя сотрудника
unsigned long number; // номер сотрудника
public:
void getdata()
{
cout << "\n Введите фамилию: "; cin >> name;
cout << " Введите номер: "; cin >> number;
}
void putdata() const
{
cout << "\n Фамилия: " << name;
cout << "\n Номер: " << number;
}
};
///////////////////////////////////////////////////////////
class manager : private employee, private student // менеджер
{
private:
char title[LEN]; // должность сотрудника
double dues; // сумма взносов в гольф-клуб
public:
void getdata()
{
employee::getdata();
cout << " Введите должность: "; cin >> title;
cout << " Введите сумму взносов в гольф-клуб: "; cin >> dues;
student::getedu();
}
void putdata() const
{
employee::putdata();
cout << "\n Должность: " << title;
cout << "\n Сумма взносов в гольф-клуб: " << dues;
student::putedu();
}
};
///////////////////////////////////////////////////////////
class executive : public manager
{
private:
float premium;
int stock;
public:
void getdata()
{
manager::getdata();
cout << " Введите премию: "; cin >> premium;
cout << " Введите количество акций: "; cin >> stock;
}
void putdata()const
{
manager::putdata();
cout << "\n премия: " << premium;
cout << "\n количество акций: " << stock;
}
};
///////////////////////////////////////////////////////////
class scientist : private employee, private student // ученый
{
private:
int pubs; // количество публикаций
public:
void getdata()
{
employee::getdata();
cout << " Введите количество публикаций: "; cin >> pubs;
student::getedu();
}
void putdata() const
{
employee::putdata();
cout << "\n Количество публикаций: " << pubs;
student::putedu();
}
};
///////////////////////////////////////////////////////////
class laborer : public employee // рабочий
{
};
///////////////////////////////////////////////////////////
int main()
{
setlocale (0, "");
manager m1;
executive e1;
scientist s1;
laborer l1;
cout << endl;
cout << "\nВвод информации о первом менеджере";
m1.getdata();
cout << "\nВвод информации о первом ученом";
s1.getdata();
cout << "\nВвод информации о первом управляющем";
e1.getdata();
cout << "\nВвод информации о первом рабочем";
l1.getdata();
cout << "\nИнформация о первом менеджере";
m1.putdata();
cout << "\nИнформация о первом ученом";
s1.putdata();
cout << "\nИнформация о первом управляющем";
e1.putdata();
cout << "\nИнформация о первом рабочем";
l1.putdata();
cout << endl;
system("pause");
return 0;
}
В 9 задаче немного неправильно работает класс data, который хранит дату.
ОтветитьУдалитьЕсть такой вариант кода.
#include "stdafx.h"
#include
using namespace std;
class DateClass
{
public:
int m_day;
int m_month;
int m_year;
void print()
{
std::cout << m_day << "/" << m_month << "/" << m_year;
}
};
DateClass today{ 12, 11, 2018 };
today.m_day = 18; // используем оператор выбора членов для выбора переменной-члена объекта today класса DateClass
today.print(); // используем оператор выбора членов для вызова метода объекта today класса DateClass
system("pause");
}