В любой программе всегда есть еще одна ошибка
Закон Мерфи
Цель работы – освоить разработку и использование контейнерного класса, который содержит в качестве член-данного другой класс (4 час.).
Задание
Разработайте собственный контейнерный класс в соответствии с вашим счастливым вариантом задания (см. табл. 4.1). В качестве член-данного класс должен содержать класс TVector, разработанный Вами в предыдущей работе, и использовать его для хранения данных.
При выполнении любого варианта задания предусмотреть такую реализацию программы, использующей разработанный вами класс, которая бы позволила убедиться в корректности реализации методов класса. В частности, во всех вариантах должен быть реализован метод вывода на монитор всех элементов массива и их количества.
Обязательно следует реализовать два варианта вашего класса: использование класса TVector с конструктором без параметров и с конструктором с параметрами.
Если в вашем задании не оговорен конкретно тип обрабатываемых данных, то он может быть любым числовым. Другими словами, объявляйте тип данных как ElemType, который описан в файле TVector.h.
Разработанный вами класс должен размещаться в отдельных файлах (.h и .cpp).
В качестве примера реализации класса Стек смотрите программу Stck . exe.
10.2. Описание вариантов заданий
Таблица 4.1.
Варианты заданий
№ вар. | Задание |
1,8 | Класс Стек (CStack) со следующими методами:
|
2,9 | Класс Очередь (CQueue) с такими же методами, как и класс Стек. Этот класс представляет собой такую структуру данных, в которой реализуется правило «первым пришел - первым вышел» |
3,10 | Класс Очередь с приоритетом (CPriorityQueue) с такими же методами, как и класс Очередь. Отличительной чертой этого класса является то, что самый большой элемент всегда находится в начале очереди, т.е. данные в очереди упорядочены. |
4,11 | Класс Ассоциативный массив (CMap), каждый элемент которого имеет не целочисленный индекс, а «имя», представляющее собой строку символов. Когда числовое значение заносится в массив, для него указывается также имя. Аналогичным образом извлечение данного из массива также выполняется по его имени. Для облегчения решаемой задачи можно принять некоторые допущения:
|
5,12 | Класс Массив (CArrChar), предоставляющий возможность задания индексов массива символьного типа. Конструктор класса должен получать в качестве параметров начальный и конечный индексы массива как данные символьного типа. Методы добавления, получения, вставки, удаления элементов массива должны получать в качестве параметра индекс массива символьного типа. |
6,13 | Класс Массив (CArrInt), предоставляющий возможность задания начального и конечного индексов массива как целых чисел. Конструктор класса должен получать в качестве параметров начальный и конечный индексы массива. Методы добавления, получения, вставки, удаления элементов массива должны получать в качестве параметра индекс массива целочисленного типа. |
7,14 | Класс Кольцо (CRing), предназначенный для хранения и обработки данных числового типа как массива. Отличительной особенностью класса является тот факт, что класс всегда «помнит» текущий индекс массива и при добавлении нового элемента массива вставляет его вслед за текущим и делает новым текущим, а при получении значения текущего элемента массива автоматически перемещается к следующему. Когда текущим становится последний элемент массива, то после получения его значения текущим должен стать первый элемент массива. |
Методические указания
В качестве иллюстрации контейнерного класса рассмотрим следующий пример. Пусть имеется класс CDate, который поддерживает обработку дат (день, месяц и год):
// Файл Date.h
#pragma once
class CDate
{
public:
CDate(void);
~CDate(void);
void setDay(int newDay);
void setMonth(int newMonth);
void setYear(int newYear);
int getDay();
int getMonth();
int getYear();
private:
int m_nDay;
int m_nMonth;
int m_nYear;
};
Реализацию этого класса разместим, как принято, в cpp-файле:
// Файл Date.cpp
#include "StdAfx.h"
#include "Date.h"
CDate::CDate(void): m_nDay(0), m_nMonth(0), m_nYear(0)
{
TRACE("Constructor CDate was called\n");
}
CDate::~CDate(void)
{
TRACE("Destructor ~CDate was called\n");
}
void CDate::setDay(int newDay){m_nDay=newDay;}
void CDate::setMonth(int newMonth){m_nMonth=newMonth;}
void CDate::setYear(int newYear){m_nYear=newYear;}
int CDate::getDay(){return m_nDay;}
int CDate::getMonth(){return m_nMonth;}
int CDate::getYear(){return m_nYear;}
Обратите внимание на реализации конструктора и деструктора класса CDate, в которые добавлен макрос TRACE для отслеживания момента их (автоматического) вызова.
Пусть также имеется класс CPerson, назначение которого состоит в обработке данных о служащих. Очевидно, что для каждого служащего надо сохранять несколько дат, например, день рождения, дата поступления на работу, даты отпусков и т.п. Для простоты ограничимся одной датой и опишем класс таким образом:
// Файл Person.h
#pragma once
#include "date.h"
Class CPerson
{
public :
CPerson(void);
~CPerson(void);
char * getFName(void);
char * getSName(void);
void setFName(char * newFName);
void setSName(char * newSName);
void setBirthDate(int Day, int Month, int Year);
int getBirthDay();
int getBirthMonth();
int getBirthYear();
private :
char *m_sFName;
char *m_sSName;
CDate m_dBirthDate;
};
=======================================================================
// Файл Person.cpp
#include "StdAfx.h"
#include "Person.h"
CPerson::CPerson(void): m_sFName(NULL), m_sSName(NULL)
{
TRACE("Constructor CPerson was called\n");
}
CPerson::~CPerson(void)
{
if(m_sFName) delete [] m_sFName;
if(m_sSName) delete [] m_sSName;
TRACE("Destructor ~CPerson was called\n");
}
char * CPerson::getFName(void)
{ return m_sFName; }
char * CPerson::getSName(void)
{ return m_sSName; }
void CPerson::setFName(char * newFName)
{
m_sFName=new char [strlen(newFName)+sizeof(char)];
strcpy(m_sFName,newFName);
}
void CPerson::setSName(char * newSName)
{
m_sSName=new char [strlen(newSName)+sizeof(char)];
strcpy(m_sSName,newSName);
}
Дата: 2019-07-30, просмотров: 217.