ООП 16 вариант
.docxМинистерство образования Республики Беларусь
Учреждение образования
«БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ»
Институт информационных технологий
Специальность: ИСиТ(вЭ)
КОНТРОЛЬНАЯ РАБОТА №1
По курсу Объектно-ориентированное программирование
Вариант № 16
Студент-заочник 1 курса (сокращенная форма обучения)
Минск, 2012
Задание
Разработать класс содержащий:
-
компоненты данные
-
методы:
а) конструктор по умолчанию
б) конструктор с параметрами
в) конструктор копирования
г) деструктор
д) методы класса для работы с данными.
Данные класса должны иметь атрибут private.
При реализации задачи 1 функцию вывода содержимого объекта реализовать как внешнюю по отношению к классу.
Задача1. Разработать класс, реализующий список (однонаправленная очередь). Элемент списка содержит информацию о товаре на складе фирмы. Элемент очереди содержит наименование товара, цену, количество и дату поставки. В классе реализовать методы поставки на склад, отгрузки со склада и формирования информации по выбранному товару.
Задача2. Создать несколько объектов (например, a и b) разработанного класса. Класс – вектор (одномерный массив). Реализовать для объектов данного класса перегрузку операции () (a(i)=k и k=b(i)). Содержимое объектов (a,b из векторов), до и после выполнения операции, вывести на экран.
Задача 1
Разработать класс, реализующий список (однонаправленная очередь). Элемент списка содержит информацию о товаре на складе фирмы. Элемент очереди содержит наименование товара, цену, количество и дату поставки. В классе реализовать методы поставки на склад, отгрузки со склада и формирования информации по выбранному товару.
Алгоритм программы:
Решено было сделать класс, в котором прямо внутри будут комманды работы с консолью, чтобы в управляемой программе было минимум кода, т.е. присоединив заголовочный файл и создав объект класса, мы вызываем метод «Menu()» класса и отдаем дальнейшую обработку объекта непосредственно классу.
Присутствует внешний метод See, который выводит информацию о складе.
Программа построена на пользовательсокм выборе в меню, ниже приведен типовой алгоритм работы:
Шаг 1. Инициализация двух переменных MyFirstWH, MySecondWH класса Warehouse. Вывод главного меню, в котором выбираем работу с первым, вторым или третьим складом. Выбираем первый склад.
Шаг 2. Выбор пункта меню работы со складом. Выберем «5 – переименовать склад» и зададим складу произвольное имя.
Шаг 3. Выбор пункта меню работы со складом. Выбираем «1 – Создать новую или обновить существующую складскую очередь». Если ранее очередь не была задана – она задается, если ранее в очередь добавлялись товары – эта команда добавит новые товары.
Шаг 4. Выбор пункта меню работы со складом. Выбираем «2 – Посмотреть что на складе», команда выдаст полный перечень товаров в списке.
Шаг 5. Выберем «8 – Посмотреть информацию о товаре по артикулу» и введем произвольный артикул, выборка по которому будет происходить.
Шаг 6. Далее выбираем «3 – отгрузка первого товара в очереди», команда отгрузит последний введеный товар со склада.
Шаг 7. Выберем «0 – Закончить с этим складом» и вернемся в главное меню.
Шаг 8. Выберем «3 – Третий склад (Копируем первый склад)». При этом создастся объект MyThirdWH класса Warehouse, который с помощью конструктора копирования полностью скопирует объект MyFirstWH и далее вызывает метод Menu объекта, что подразумевает под собой начало работы с этим объектом.
Шаг 9. После произвольных операций и возврата в главное меню выбираем «0 – Уходим отсюда» и программа готовится к завершению. Удаляются динамические объекты.
Шаг 10. Завершение работы программы.
Исходный код класса:
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct Product {
char *Article; //Артикул
char *Name; //Имя
int Price; //Цена
int Quantity; //Количество
int Day; //День
int Month; //Месяц
int Year; //Год
Product *Next; //Ссылка на следующий элемент очереди
};
class Warehouse {
public:
Warehouse(void); // Конструктор класса
Warehouse(char *NewName); // Конструктор класса c параметрами
Warehouse(const Warehouse & _src); //Конструктор копирования
virtual ~Warehouse(){Clean();}; // Деструктор класса
// ------------Методы
void Menu(void); //главное меню объекта класса
void SetName(char *NewName); //Назначение имени объекта
void Add(void); //Добавить элемент в очередь
void See(void); //Просмотреть содержимое очереди
void See(char *Article); //Просмотреть определенный товар по артикулу
void Delete(void); //Удалить последний товар
void Delete(char *Article); //Удалить товар по артикулу
void Clean(void); //Очистить очередь
Product* Get(){return Container;};
bool Exist(void); //Проверка на существование очереди
private:
// ------------Свойства
char *Name; //Имя объекта
Product *Container; // Очередь
};
Warehouse::Warehouse(void) {
Container = NULL;
Name=NULL;
}
Warehouse::Warehouse(char *NewName) {
Container = NULL;
SetName(NewName);
}
Warehouse::Warehouse(const Warehouse & _src) {
Warehouse TempWH;
Product *temp;
Product *source = _src.Container;
while(source){
if (!(temp = (Product*) calloc(1, sizeof(Product)))) {
puts("Нет свободной памяти");
return;
}
temp->Article = (char*)malloc(255 * sizeof(char));
temp->Name = (char*)malloc(255 * sizeof(char));
temp->Article=source->Article;
temp->Name=source->Name;
temp->Price=source->Price;
temp->Quantity=source->Quantity;
temp->Day=source->Day;
temp->Month=source->Month;
temp->Year=source->Year;
if (!(TempWH.Container)) {
temp->Next = NULL; // очередной элемент очереди
TempWH.Container = temp; // передвигаем указатель на хвост
}
else {
temp->Next = TempWH.Container; // очередной элемент очереди
TempWH.Container = temp; // передвигаем указатель на хвост
}
source=source->Next;
}
source = TempWH.Container;
while(source){
if (!(temp = (Product*) calloc(1, sizeof(Product)))) {
puts("Нет свободной памяти");
return;
}
temp->Article = (char*)malloc(255 * sizeof(char));
temp->Name = (char*)malloc(255 * sizeof(char));
temp->Article=source->Article;
temp->Name=source->Name;
temp->Price=source->Price;
temp->Quantity=source->Quantity;
temp->Day=source->Day;
temp->Month=source->Month;
temp->Year=source->Year;
if (!Container) {
temp->Next = NULL; // очередной элемент очереди
Container = temp; // передвигаем указатель на хвост
}
else {
temp->Next = Container; // очередной элемент очереди
Container = temp; // передвигаем указатель на хвост
}
source=source->Next;
}
SetName(_src.Name);
}
void Warehouse::Menu(void) {
char *st;
st = (char *)malloc(255);
clrscr();
while (1) {
if(!Name){
puts("Работа с безымянным складом:\n\n");
} else {
printf("Работа со складом '%s':\n\n", this->Name);
}
puts("Выберите операцию:");
puts(" 1 - Создать новую или обновить существующую складскую очередь");
puts(" 2 - Посмотреть, что на складе");
puts(" 3 - Отгрузка первого товара в очереди");
puts(" 4 - Отгрузка товара по артикулу");
puts(" 5 - Переименовать склад");
puts(" 6 - Очистить складскую очередь");
puts(" 7 - Очистить экран");
puts(" 8 - Посмотреть информацию о товаре по артикулу");
puts(" 0 - Закончить с этим складом");
fflush(stdin);
switch (getch()) {
case '1':
this->Add();
break;
case '2':
this->See();
break;
case '3':
if (this->Exist())
this->Delete();
break;
case '4':
if (this->Exist()) {
fflush(stdin);
puts("Введите артикул, который хотите удалить из очереди:");
gets(st);
this->Delete(st);
}
break;
case '5':
fflush(stdin);
puts("Введите новое имя склада:");
gets(st);
this->SetName(st);
break;
case '6':
this->Clean();
break;
case '7':
clrscr();
break;
case '8':
if (this->Exist()) {
fflush(stdin);
puts("Введите интересующий вас артикул:");
gets(st);
this->See(st);
}
break;
case '0':
return;
default:
printf("Ошибка, повторите \n");
}
}
}
void Warehouse::SetName(char *NewName) {
this->Name = NewName;
return;
}
void Warehouse::Add(void) {
Product *temp;
puts("Создание очереди:\n");
do {
if (!(temp = (Product*) calloc(1, sizeof(Product)))) {
puts("Нет свободной памяти");
return;
}
temp->Article = (char*)malloc(255 * sizeof(char));
temp->Name = (char*)malloc(255 * sizeof(char));
puts("Введите артикул товара:");
fflush(stdin);
gets(temp->Article);
puts("Введите наименование товара:");
fflush(stdin);
gets(temp->Name);
puts("Введите цену");
fflush(stdin);
scanf("%d", &(temp->Price));
puts("Введите количество");
fflush(stdin);
scanf("%d", &(temp->Quantity));
puts("Введите дату в формате DD.MM.YYYY");
fflush(stdin);
do {
scanf("%d.%d.%d", &(temp->Day), &(temp->Month), &(temp->Year));
if (
((temp->Day<1)||(temp->Day>31))||
((temp->Month<1)||(temp->Month>12))||
((temp->Year<1970)||(temp->Year>2100))
)
{
temp->Day=0;
temp->Month=0;
temp->Year=0;
puts("Напортачили вы с вводом. \nПопробуйте ввести адекватную дату в формате DD.MM.YYYY:\n");
}
} while(temp->Day==0);
if (!Container) {
temp->Next = NULL; // очередной элемент очереди
Container = temp; // передвигаем указатель на хвост
}
else {
temp->Next = Container; // очередной элемент очереди
Container = temp; // передвигаем указатель на хвост
}
puts("Создать следующий товар?(y/n):");
fflush(stdin);
}
while (getch() == 'y');
}
void Warehouse::See(void) {
Product *temp = Container;
fflush(stdin);
puts("Вывод содержимого очереди:\n");
if (!temp) {
puts("Очередь пуста.");
return;
}
do {
printf("\n/--------------ТОВАР\n");
printf("Артикул:%s\n", temp->Article);
printf("Наименование:%s\n", temp->Name);
printf("Цена:%d\n", temp->Price);
printf("Количество:%d\n", temp->Quantity);
printf("Общая цена:%d\n", temp->Quantity*temp->Price);
printf("Дата:%d.%d.%d\n", temp->Day, temp->Month, temp->Year);
printf("/--------------/ТОВАР\n\n");
temp = temp->Next;
}
while (temp);
return;
}
void Warehouse::See(char *Article) {
Product *temp = Container;
fflush(stdin);
puts("Ну посмотрим, что у нас есть с таким артикулом:\n");
if (!temp) {
puts("Очередь пуста.");
return;
}
do {
if (!strcmp(temp->Article, Article)) {
printf("\n/--------------ТОВАР\n");
printf("Артикул:%s\n", temp->Article);
printf("Наименование:%s\n", temp->Name);
printf("Цена:%d\n", temp->Price);
printf("Количество:%d\n", temp->Quantity);
printf("Общая цена:%d\n", temp->Quantity*temp->Price);
printf("Дата:%d.%d.%d\n", temp->Day, temp->Month, temp->Year);
printf("/--------------/ТОВАР\n\n");
}
temp = temp->Next;
}
while (temp);
return;
}
void Warehouse::Delete(void) {
Product *pr;
if (!Container) {
puts("Очередь пуста.");
return;
}
if (!Container->Next) // в очереди только один элемент
{
free(Container->Article);
free(Container->Name);
free(Container);
Container = NULL; // очередь пуста
return;
}
pr = Container;
while (pr->Next->Next)
pr = pr->Next;
free(pr->Next->Article);
free(pr->Next->Name);
free(pr->Next); // удаление первого элемента из очереди
pr->Next = NULL;
return;
}
void Warehouse::Delete(char *Article) {
Product *f, *pr;
if (!Container) {
puts("Очередь пуста.");
return;
}
if (!Container->Next && // в очереди только один элемент
!strcmp(Container->Article, Article)) {
free(Container->Article);
free(Container->Name);
free(Container);
Container = NULL; // очередь пуста
return;
}
pr = Container;
f = pr; // далее f предыдущий к pr элемент
while (pr) {
if (!strcmp(pr->Article, Article)) // найден элемент со строкой Article
{
if (pr == Container) {
Container = pr->Next;
free(pr->Article);
free(pr->Name);
free(pr);
f = pr = Container;
}
else {
f->Next = pr->Next; // обходим элемент pr
free(pr->Article);
free(pr->Name);
free(pr); // удаляем элемент pr очереди
pr = f->Next; // выбор следующего элемента очереди pr
}
}
else {
f = pr;
pr = pr->Next;
} // переход к следующему элементу
}
}
void Warehouse::Clean(void) {
Product *clean;
fflush(stdin);
puts("Вывод содержимого очереди:\n");
if (!Container) {
puts("Очередь пуста.");
return;
}
do {
clean = Container;
Container = Container->Next;
free(clean->Article);
free(clean->Name);
free(clean);
}
while (Container);
fflush(stdin);
puts("Очередь очищена!");
return;
}
bool Warehouse::Exist(void) {
if (!Container) {
return false;
}
else {
return true;
}
}
void See(Product *Container) {
Product *temp = Container;
fflush(stdin);
puts("Вывод содержимого очереди:\n");
if (!temp) {
puts("Очередь пуста.");
return;
}
do {
printf("\n/--------------ТОВАР\n");
printf("Артикул:%s\n", temp->Article);
printf("Наименование:%s\n", temp->Name);
printf("Цена:%d\n", temp->Price);
printf("Количество:%d\n", temp->Quantity);
printf("Общая цена:%d\n", temp->Quantity*temp->Price);
printf("Дата:%d.%d.%d\n", temp->Day, temp->Month, temp->Year);
printf("/--------------/ТОВАР\n\n");
temp = temp->Next;
}
while (temp);
return;
}
Код программы, использующий класс Warehouse:
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#include "Sklad.cpp"
int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
Warehouse MyFirstWH,MySecondWH;
char *st;
st=(char *)malloc(10);
clrscr();
puts("Начнем? :)\n");
while(1)
{
clrscr();
puts("Выбираем склад:");
puts(" 1 - Первый склад");
puts(" 2 - Второй склад");
puts(" 3 - Третий склад(Копируем первый склад)");
puts(" 4 - Вывести содержимое первых двух складов");
puts(" 0 - Уходим отсюда");
fflush(stdin);
switch(getch())
{
case '1': MyFirstWH.Menu(); break;
case '2': MySecondWH.Menu(); break;
case '3':
{Warehouse MyThirdWH(MyFirstWH);
MyThirdWH.Menu();
};
break;
case '4':
{
fflush(stdin);
See(MyFirstWH.Get());
See(MySecondWH.Get());
getch();
fflush(stdin);
}
break;
case '0':
return 0;
default:
printf("Ошибка, повторите \n");
}
}
}
Результат работы:
Создание очереди:
Просмотр товаров:
Поиск товара:
Задача 2
Создать несколько объектов (например, a и b) разработанного класса. Класс – вектор (одномерный массив). Реализовать для объектов данного класса перегрузку операции () (a(i)=k и k=b(i)). Содержимое объектов (a,b из векторов), до и после выполнения операции, вывести на экран.
Алгоритм программы:
При выборе в главном меню пункта один происходит выполнение задания:
Шаг 1.Инициализация двух переменных a и b вызовом конструкторов по умолчанию.
Шаг 2. Производится ввод данных в массивы a и b. a[1,3,5,7], b[2,4,6,8]. После этого они выводятся на экран. Создается объект с и с помощью конструктора копирования в него загружаются данные из объекта b.
Шаг 3. С помощью оператора () происходит a(1)=0.
Шаг 4. Объявляется переменна temp и ей присваивается значение a(3).
Шаг 5. Элементу b(1) присваивается значение элемента a(1).
Шаг 6. Массивы a,b,с и переменная temp выводятся на экран как результат.
Исходный код класса:
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
template <class Type>
class MVector {
public:
int Length;
MVector(){ //Конструктор по умолчанию
this->Length=0;
this->Massive=(Type*) malloc(sizeof(Type)*0);
};
MVector(int NewLength){ //Конструктор с параметрами. Нулевой массив
//с размером NewLength.
this->Length=NewLength;
this->Massive=(Type*) malloc(sizeof(Type)*NewLength);
for (int i = 0; i < NewLength; i++) {
this->Add(0);
}
};
MVector(const MVector<Type> & _src){ //Конструктор копирования
this->Length=_src.Length;
this->Massive=(Type*) malloc(sizeof(Type)*_src.Length);
for (int i = 0; i < _src.Length; i++) {
this->Massive[i]=_src.Massive[i];
}
};
~MVector(){ //Деструктор
free(Massive);
};
void Add(const Type &val); //Добавить в конец массива элемент.
void See(void); //Просмотр содержимого массивов. Только для int.
Type& operator()(int i); //Оператор (). Аналогичен [] для массивов.
private:
Type *Massive;
};
template <class Type>
void MVector<Type>::Add(const Type &val) {
this->Length++;
this->Massive=(Type*) realloc (this->Massive, (this->Length*sizeof(Type)));
this->Massive[this->Length-1]=val;
};
template <class Type>
void MVector<Type>::See(void) {
try
{
for (int i = 0; i < this->Length; i++) {
printf("[%d]: %d\n",i,this->Massive[i]);
}
} catch(...) {
printf("Вывод работает только для целочисленного вектора.\n");
}
}
template <class Type>
Type& MVector<Type>::operator()(int i) {
if ((i+1)<=this->Length) {
return Massive[i];
}
}
Код главной программы, использующей класс:
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <conio.h>
#include "Vector.h"
int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleOutputCP(1251);
SetConsoleCP(1251);
MVector<int> a,b;
clrscr();
while(1){
puts("Выбираем действие:");
puts("1 - Выполнить задание");
puts("2 - Добавить элемент массива");
puts("3 - Посмотреть массив");
puts("4 - Переопределить элемент");
puts("5 - Присвоить переменной значение элемента массива");
puts("0 - Выйти");
fflush(stdin);
switch(getch())
{
case '1':
{
a.Add(1);
a.Add(3);
a.Add(5);
a.Add(7);
b.Add(2);
b.Add(4);
b.Add(6);
b.Add(8);
MVector<int> c=b;
puts("Начальные данные:");
puts("Массив 'a'");
a.See();
puts("Массив 'b'");
b.See();
a(1)=0;
int temp;
temp=a(3);
b(1)=a(1);
puts("Конечные данные:");
puts("Массив 'a'");
a.See();
puts("Массив 'b'");
b.See();
puts("Массив 'c'");
c.See();
puts("Переменная temp");
printf("temp = %d\n",temp);
}
break;
case '2':
do{
puts("Добавить элемент:");
fflush(stdin);
int temp;
scanf("%d", &temp);
a.Add(temp);
fflush(stdin);
puts("Продолжить?(y/n)");
fflush(stdin);
} while(getch()=='y');
break;
case '3': a.See(); break;
case '4':
do{
puts("Введите индекс элемента:");
fflush(stdin);
int temp_index;
scanf("%d", &temp_index);
puts("Введите значение элемента:");
fflush(stdin);
int temp_value;
scanf("%d", &temp_value);
fflush(stdin);
a(temp_index)=temp_value;
printf("a[%d] = %d", temp_index, temp_value);
puts("Продолжить?(y/n)");
fflush(stdin);
} while(getch()=='y');
break;
case '5':
do{
int temp=0,temp_index;
puts("Введите индекс элемента:");
fflush(stdin);
scanf("%d", &temp_index);
temp=a(temp_index);
printf("Временная переменная равна %d", temp);
fflush(stdin);
puts("Продолжить?(y/n)");
fflush(stdin);
} while(getch()=='y');
break;
case '0':
return 0;
default:
printf("Ошибка, повторите \n");
}
}
}
Результат работы:
Литература
1. Объектно-ориентированное программирование на C++ / А.Пол.
2. Самоучитель C/C++ и C++ Builder 2007 / Пахомов Б.
3. Язык С++ - Учебное пособие / И. Ф. Астахова, С. В. Власов, В.В. Фертиков, А.В. Ларин.
7. Форум программистов и сисадминов CyberForum.ru (Электронный ресурс). URL: http://www.cyberforum.ru/.