Таблица данных произвольных типов в памяти
Разработка интерфейса для объединения в структуру данных множества объектов различных классов (абстрактный базовый класс TObject). Создание таблиц (коллекций) объектов с помощью механизма объектно-ориентированного программирования - полиморфизма.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 06.08.2013 |
Размер файла | 175,7 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
ФГБОУВПО
БРЯНСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Кафедра «Информатика и программное обеспечение»
КУРСОВАЯ РАБОТА
Таблица данных произвольных типов в памяти
Вариант № 27
Выполнил студент гр. 11-ПрИ,
Васин А.В.
Брянск 2012
Оглавление
- Задание
- 1. Теоретические аспекты
- 2. Реализация
- 2.1 Абстрактный базовый класс
- 2.2 Классы наследники
- 2.3 Класс таблицы объектов произвольных типов
- 3. Пример работы программы
- Заключение
- ВВЕДЕНИЕ
- Виртуальные методы -- один из важнейших приёмов реализации полиморфизма. Они позволяют создавать общий код, который может работать как с объектами базового класса, так и с объектами любого его класса-наследника. При этом базовый класс определяет способ работы с объектами, любые его наследники могут предоставлять конкретную реализацию этого способа. В данной работе с помощью виртуальных методов была реализована таблица (коллекция) объектов произвольных типов.
- ЗАДАНИЕ
- Необходимо разработать интерфейс для объединения в структуру данных множества объектов различных классов - абстрактный базовый класс object, для которого предусмотреть виртуальные методы: загрузки объекта из текстовой строки, выгрузки объекта в текстовую строку в динамической памяти, добавление объекта в последовательный двоичный файл, чтения объекта из последовательного двоичного файла, возврата указателя на строку с именем класса, сравнения двух объектов, объединения двух объектов (сложения), создания динамической копии объекта. Сделать классы хранимых объектов производными от абстрактного базового класса TObject.
1. Теоретические аспекты
Для создания таблицы (коллекции) объектов различных типов необходимо использовать механизм объектно-ориентированного программирования под названием полиморфизм.
Полиморфизм -- возможность объектов с одинаковой спецификацией иметь различную реализацию. В данном случае спецификацией будет являться класс TObject. В нём описаны чисто виртуальные функции, предоставляющие обобщенный интерфейс для частных классов. Частные классы, в свою очередь, предоставляют реализацию виртуальных функций для работы с ними.
Таким образом, в таблице разнотипных объектов будут содержаться указатели на абстрактный класс. Далее, по мере работы с ней, каждый указатель будет ссылаться на частные объекты, унаследованные от абстрактного класса. Работа с ними будет происходить через виртуальные функции, описанные в базовом абстрактном классе. Таким образом, будет проявляться концепция полиморфизма - объекты, имеющие один общий интерфейс (абстрактный базовый класс), имеют различные реализации.
2. Реализация
2.1 Абстрактный базовый класс
Для того чтобы производные классы гарантированно имели уникальную реализацию интерфейсных функций, опишем их в базовом классе как чисто виртуальными. Таким образом, базовый класс становится абстрактным. Этим мы заранее предотвращаем потенциальные ошибки при наследовании.
Итоговый базовый класс представлен в листинге 3.1.
#define CMP_ERROR -2
#define CMP_A_LESS_B -1
#define CMP_A_EQUAL_B 0
#define CMP_A_GREATER_B 1
class TObject
{
public:
virtual void LoadFromString(const char* str)=0;//загрузить данные из строки
virtual char* SaveToString() const=0;//создать строку и записать туда данные
virtual const char* ClassName() const=0;//получить имя класса в виде строки
virtual char Compare(TObject &b) const=0;//сравнить два объекта
virtual TObject* Clone() const=0;//создать динамическую копию объекта
/*объединить объекты (каждый производный класс интерпретирует эту операцию по-разному)*/
virtual void Unite(TObject&)=0;
virtual ~TObject()//виртуальный деструктор
{
};
//перегруженные операторы ввода/вывода из потока
friend std::istream& operator >> (std::istream&, TObject&);
friend std::ostream& operator << (std::ostream&, TObject&);
//функции, для записи данных в двоичном формате в файл
virtual void SaveToFile(FILE *)=0;
virtual void LoadFromFile(FILE *)=0;
};
Листинг 3.1 Абстрактный базовый класс, описывающий интерфейсную часть для работы с объектами производных классов.
Необходимо отдельно прокомментировать функцию Compare. Она принимает ссылку на объект абстрактного класса. В производных классах эта функция должна удостовериться, что сравниваемые объекты имеют одинаковый тип. Если объекты разно типовые, то функция должна вернуть значение CMP_ERROR. Иначе, после сравнения возвращается CMP_A_LESS_B или CMP_A_EQUAL_B, или CMP_A GREATER_B.
Определение дружественных перегруженных операторов >> и << :
std::istream& operator >> (std::istream& stream, TObject& obj)
{
char buf[1024];//строка с данными
stream>>buf; //считываем строку из потока
//вызываем виртуальную функцию для объекта obj c аргументом - строка buf:
obj.LoadFromString(buf);
return stream;
}
std::ostream& operator << (std::ostream& stream, TObject& obj)
{
char* str=obj.SaveToString();//сохранить данные в текстовую строку
stream<<str;//вывести строку на экран
delete[] str;//удалить строку из динамической памяти
return stream;
}
2.2 Классы наследники
В качестве класса наследника рассмотрим класс TInteger, являющийся «обёрткой» обычных целых чисел. В листинге 3.2 приведено описание интерфейса класса.
#include "TObject.h"
class TInteger:public TObject
{
int data;//данные
public:
TInteger();//пустой конструктор
TInteger(TInteger&);//конструктор копирования
~TInteger();//виртуальный деструктор
TInteger operator=(TInteger&);
//ниже объявление уже не чистых виртуальных функций, унаследованных от TObject
const char *ClassName() const;
TInteger* Clone() const;
char Compare(TObject&) const;
void LoadFromString(const char*);
char* SaveToString() const;
void Unite(TObject&);
void SaveToFile(FILE *);
void LoadFromFile(FILE *);
};
Листинг 3.2 Интерфейс класса TInteger
Рассмотрим полиморфные определения виртуальных функций, унаследованных от класса TObject.
Константная функция, возвращающая имя класса в виде константной строки:
const char *TInteger::ClassName() const
{
return "TInteger";
}
Константная функция, создающая копию объекта в динамической области памяти:
TInteger* TInteger::Clone() const
{
return new TInteger(*(TInteger*)this);
}
Константная функция сравнения двух объектов:
char TInteger::Compare(TObject& b) const
{
if(strcmp(ClassName(),b.ClassName())!=0)//если имена классов не совпадают
return CMP_ERROR;//вернуть информацию об ошибке
if(data<((TInteger&)b).data)//если данные меньше данных другого объекта
return CMP_A_LESS_B;//вернуть информацию «А меньше, чем Б»
if(data==((TInteger&)b).data)//если равны
return CMP_A_EQUAL_B;//вернуть «А эквивалентно Б»
return CMP_A_GREATER_B;//во всех других случаях «А больше, чем Б»
}
Функция считывания информации из строки:
void TInteger::LoadFromString(const char *inStr)
{
if(inStr==NULL || strlen(inStr)==0)
return;//остановить выполнение, если строка пуста или указатель - NULL
sscanf(inStr,"%d",&data);//считать целое число из строки
}
Константная функция сохранения данных в строку:
char* TInteger::SaveToString() const
{
//размерерность целого числа (32 разрядная система) не превышает 16 знаков:
char buf[16];
sprintf(buf,"%d",data);//записать данные в строку
//создать строку, скопировать туда данные из buf и вернуть указатель:
return strdup(buf);
}
Функция объединения двух однотипных объектов. Для целых чисел - это арифметическое сложение.
void TInteger:Unite(TObject &b)
{
if(strcmp(ClassName(),b.ClassName())!=0)//если имена классов не совпадают
return;//закончить выполнение
data+=((TInteger&)b).data;//сложение
}
Функции сохранения и записи в файл. Предполагается, что файл уже открыт из вне, и функции передаётся уже существующий дескриптор.
void TInteger::SaveToFile(FILE *f)
{
if(f==NULL)
return;
fwrite(&data,sizeof(data),1,f);//запись в бинарный файл f данных
}
void TInteger::LoadFromFile(FILE *f)
{
if(f==NULL)
return;
fread(&data,sizeof(data),1,f);//считать данные из файла
}
2.3 Класс таблицы объектов произвольных типов
Итак, после того, как были определены все необходимые производные неабстрактные классы от класса TObject, можно использовать их для реализации концепции полиморфизма в виде коллекции объектов разного типа. Сама коллекция не хранит информацию о типах хранимых объектов, она хранит таблицу указателей на объекты класса TObject. Исключение - функция Load загрузки коллекции из файла и перегруженный дружественный оператор >>. Им необходимо знать имена всевозможных производных классов, для того чтобы создавать их экземпляры, но не более того.
Интерфейс коллекции представлен в листинге 3.3.
#include "TObject.h"
class TCollection
{
TObject **ppObjects;//динамический массив указателей на объекты типа TObject
unsigned size;//размер массива
public:
TCollection();//конструктор
TCollection(TCollection&);//конструктор копии
~TCollection();//деструктор
inline unsigned Size();//возвращает размер таблицы
void Add(TObject *pObj);//добавляет указатель на объект в конец таблицы
int Find(TObject* pObj);//ищет в таблице указатель pObj и возвращает индекс
TObject* Remove(unsigned i);//удаление по индексу
TObject* Remove(TObject*);//удаление по указателю
TObject* Access(unsigned i);//доступ к объекту по индексу
void Delete(unsigned i);//удаление объекта по индексу
void Clear();//очистка все коллекции
void Save(const char *fileName);//сохранить коллекцию в файл fileName
void Load(const char *fileName);//загрузить коллекцию из файла
//перегруженные дружественные операторы
friend std::istream& operator >> (std::istream&, TCollection&);
friend std::ostream& operator << (std::ostream&, TCollection&);
};
Листинг 3.3 Интерфейс для работы с коллекцией объектов разного типа
Рассмотрим наиболее важные с точки зрения концепции полиморфизма методы этой коллекции. Все остальные функции выполняют простую работу с указателями и памятью.
Функция сохранения коллекции в файл представлена ниже, в листинге 3.4. Перед тем, как сохранить непосредственно данные каждого объекта, функция сначала записывает имена классов этих объектов, для того, чтобы их можно было в дальнейшем восстановить при загрузке.
void TCollection::Save(const char *fileName)
{
FILE *f=fopen(fileName,"wb");//открыть файл в двоичном режиме для записи
if(f==NULL)
return;
for(unsigned i=0;i<size;i++)//рассмотрим каждый объект в таблице
{
//указатель на строку с именем класса:
const char *className=ppObjects[i]->ClassName();
unsigned char len=strlen(className);//длина строки с именем класса
fwrite(&len,sizeof(len),1,f);//записать длину строки в файл
//записать саму строку:
fwrite(className,sizeof(className[0]),len,f);
ppObjects[i]->SaveToFile(f);//сохранить сам объект в файл
}
fclose(f);//закрыть файл
}
Листинг 3.4 Функция сохранения коллекции в файл.
Функция загрузки коллекции из файла представлена в листинге 3.5. Этой функции необходимо знать названия классов для создания конкретных объектов.
void TCollection::Load(const char *fileName)
{
FILE *f=fopen(fileName,"rb");
if(f==NULL)
return;
Clear();//очистить коллекцию
while(1)
{
char len;//размер строки с именем класса
char className[256];//строка с именем класса
fread(&len,sizeof(len),1,f);//считать размер строки
if(feof(f))//если файл закончился
break;//остановить цикл
fread(className,sizeof(className[0]),len,f);//считать имя класса
className[len]='\0';
TObject *p=NULL;//указатель на объект произвольного типа
if(strcmp(className,"TInteger")==0)//если в файле было TInteger
p=new TInteger;//создать экземпляр класса TInteger
//иначе если в файле было TNumber
else if(strcmp(className,"TNumber")==0)
p=new TNumber;//то создать объект типа TNumber
if(p!=NULL)//если объект удалось создать
{
p->LoadFromFile(f);//считать его данные из файла
Add(p);//и добавить в коллекцию
}
//иначе, если объект не был создан, то дальнейшая корректная работа не возможна, //необходимо остановить выполнение функции:
else
return;
}
fclose(f);
}
Листинг 3.5 Функция загрузки коллекции из файла.
Перегруженные операторы ввода/вывода представлены в листинге 3.6.
std::ostream& operator << (std::ostream& stream, TCollection& col)
{
for(unsigned i=0; i<col.size; i++)
//сначала выводится номер элемента в коллекции, потом тип, потом вызывается
//дружественный оператор << класса TObject
stream<<'['<<i<<"]: "<<col.ppObjects[i]->ClassName()<<": "<<*col.ppObjects[i]<<'\n';
return stream;
}
std::istream& operator >> (std::istream& stream, TCollection& col)
{
char className[256];
stream>>className;//считываем из консоли строку с именем класса
//далее пытаемся создать объект с подходящим типом
TObject *p=NULL;
if(strcmp(className,"TInteger")==0)
p=new TInteger;
else if(strcmp(className,"TNumber")==0)
p=new TNumber;
if(p!=NULL)//если создать удалось
{
stream >>*p;//считываем сам объект с помощью перегруженного оператора
col.Add(p);//добавить в таблицу указатель на объект
}
return stream;
}
Листинг 3.6 Перегруженные дружественные операторы ввода/вывода в поток.
интерфейс класс таблица полиморфизм
3. Пример работы программы
Ниже, на рисунке 1, представлен скриншот коллекции разно типовых объектов. Сначала данные загружаются из ранее созданного файла output.txt. Далее происходит добавление и модификация элементов.
Рис. 1 Пример коллекции объектов.
ЗАКЛЮЧЕНИЕ
В результате выполнения работы был подробно изучен механизм работы виртуальных функций. Очевидным преимуществом механизма является возможность реализовать концепцию полиморфизма удобными средствами. Недостатком - наличие таблицы виртуальных методов требует дополнительную память, а также увеличения времени при вызове виртуально функции, т.к. доступ к ней происходит не сразу, а только после разыменовывания указателя, что замедляет вызов.
Размещено на Allbest.ru
Подобные документы
Причины возникновения объектно-ориентированного программирования. Графическое представление классов; их отличия от других абстрактных типов данных. Типы абстракции, используемые при построении объекта. Сущность инкапсуляции, наследования и полиморфизма.
контрольная работа [222,1 K], добавлен 04.06.2014Концепция объектно-ориентированного программирования. Объектно-ориентированные языки программирования: Smalltalk, Object Pascal, CLOS и C++. Понятие "Объект" и "Класс". Управление доступом к элементам данных классов. Определение функций-членов класса.
реферат [24,5 K], добавлен 28.10.2011Общие и отличительные черты объектов, связь между ними. Принципы организации иерархии и понятия объектно-ориентированной парадигмы программирования. Анализ предметной области, определение абстрактных типов данных, проектирование классов и коллекций.
курсовая работа [2,1 M], добавлен 11.03.2016Свойства объектно-ориентированного языка программирования. Понятия инкапсуляции и наследования. Виртуальные функции и полиморфизм. Инициализация экземпляра объекта с помощью конструктора. Динамическое создание объектов. Совместимость объектных типов.
реферат [17,0 K], добавлен 15.04.2015Описание классов данных. Основное меню программы. Добавление и удаление объектов. Вывод устройств хранения в указанном ПК. Устройство хранения, класс ноутбук, класс жёсткий диск, класс персональный компьютер, класс планшет и класс Flash-память.
курсовая работа [1,8 M], добавлен 30.03.2014Разработка базы данных с информацией о сотрудниках, товарах, со справочником типов товаров средствами системы управления базами данных MySQL с помощью SQL-запросов. Разработка инфологической модели предметной области. Структура таблиц, полей базы данных.
контрольная работа [648,7 K], добавлен 13.04.2012Этапы проектирования базы данных, определение целей и содержание таблиц. Добавление данных и создание других объектов базы данных. Даталогическая модель: структуризация, нормализация, схемы данных. Порядок, принципы создания пользовательского интерфейса.
курсовая работа [1,3 M], добавлен 26.03.2013Изображение класса на диаграмме UML. Инкапсуляция как средство защиты его внутренних объектов. Использование принципа полиморфизма для реализации механизма интерфейсов. Создание новых классов путем наследования. Ассоциация как вид отношений между ними.
лекция [516,6 K], добавлен 03.12.2013Использование объектно-ориентированного программирования - хорошее решение при разработке крупных программных проектов. Объект и класс как основа объектно-ориентированного языка. Понятие объектно-ориентированных языков. Языки и программное окружение.
контрольная работа [60,1 K], добавлен 17.01.2011Основные понятия объектно-ориентированного программирования в PHP5. Структурный и объектно-ориентированный подход. Класс как абстрактный тип. Реализация класса. Конструкторы и деструкторы. Функция l_visited_style изменение стиля посещенных ссылок.
курсовая работа [433,2 K], добавлен 13.06.2008