Разработка программного комплекса на языке программирования С++



СОДЕРЖАНИЕ

Введение

Целью курсовой работы является: изучение принципов объектно-ориентированного программирования на базе языка программирования С++; приобретение навыков высокоуровневого проектирования многомодульных программ.

Заданием для курсовой работы является разработка программного комплекса на языке программирования С++ с использованием принципов объектно-ориентированного программирования.

Согласно индивидуальному заданию необходимо разработать программный комплекс для ведения учёта памятников города. Множество памятников представляют собой массив, элементами которого являются любые из следующих четырех типов памятников: здание, квартал, площадь, скульптура.

Для всех памятников имеются как общие данные, так возможно и специфические.

Общие данные содержат следующие поля:

  1. год создания (integer);
  2. название (string);
  3. годовая стоимость расходов на содержание (longint);

По заданию программный комплекс должен быть способен выполнять следующие действия:

При выполнении работы необходимо придерживаться следующих ограничений:

  1. ОПИСАНИЕ ПРОГРАММНОГО КОМПЛЕКСА
    1. Структура программного комплекса

Программный комплекс состоит из следующих модулей:

− ClassFile.cpp;

− FunctionFile.cpp;

− main.cpp.

global.h.

На рисунке 1 показана схема подключения модулей.

Рисунок 1 – Схема подключения модулей

МодульClassFile.cpp содержит описание всех используемых в программе классов. А точнее базовый класс памятника и четыре его наследника (здание, квартал, площадь и скульптура), а также класс оболочка, который содержит динамический массив и все функции для работы с массивом памятника (добавление, удаление, сортировка и т.д.)

МодульFunctionFile.cpp содержит различные вспомогательные функции. Это и вывод на экран различных частей таблицы и вывод различных меню, а также выбор имени файла.

Модульmain.cpp  содержит точку входа в программу, в которой находится операторswitch для выбора необходимых действий.

Файлglobal.h  является связующим звеном, где описаны все стандартные библиотеки и функции из файлаFunctionFile.cpp

  1. МодульClassFile.cpp

В модуле описаны следующие классы:

Pamiatnik;

Zdanie;

Kvartal;

Square;

Skulptura;

− Massiv_Pamiatnikov.

Иерархия классов представлена на рисунке 2.

Рисунок 2 – Иерархия классов

  1. КлассPamiatnik

КлассPamiatnik является базовым классом для всех памятников. Именно поэтому он содержит все общие поля и все общие методы. Ко всему прочему данный класс считается абстрактным, т.е. нельзя непосредственно создавать экземпляры этого класса. Данный класс предназначен только как шаблон для создания других классов памятника. Однако, несмотря на это, он содержит в себе множество методов, которые могут вызывать наследники.

КлассPamiatnik содержит следующие поля:

-Set_God– Год основания памятника;

-Set_Stoimost – Стоимость расходов на содержание памятника;

-Set_Name – Название памятника;

-Type– Тип памятника. Используется для того, чтобы каждому памятнику присвоить соответствующее значение в данном поле. Значение именно из этого поля будет использоваться каждым классом, когда он будет создавать строковое представление всех своих ключевых полей для сохранения в файл.

-prev – указатель на предыдущий памятник в массиве.

-next – указатель на следующий памятник в массиве.

Поляprev иnext предназначены для построения динамического массива. Принцип динамического массива заключается в том, что все его элементы не обязаны находиться в памяти последовательно друг за другом. Однако все элементы массива должны быть выстроены в определённую последовательность. При такой концепции сам массив должен знать элемент, который является первым, чтобы именно с него начать работу с массивом, а также должен знать последний элемент, для того, чтобы знать, куда добавлять следующий элемент. Таким образом, с помощью полейprev иnext каждый памятник точно знает своё место в массиве.

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

Так как все ключевые поля являются закрытыми, то необходимо в полеpublic  создать методы для записи и чтения данных в/из этих ключевых полей. Методы для записи имеют в своём названии словоSet, а методы для получения значения –Get.

В связи с тем, что в программе необходимо предусмотреть возможность пользователю добавить новый памятник, в том числе и вручную. Поэтому классPamiatnik содержит методVvod. С помощью данного метода все наследники будут делегировать полномочия родителю по вводу общих ключевых полей, которые также описаны в родителе.

МетодDraw в классеPamiatnik является абстрактным. Дело в том, что классPamiatnik не будет непосредственно создаваться, поэтому и выводить свои данные ему незачем. А вот наследники обязаны будут выводить свои данные на экран. Поэтому в базовом классе данный метод является абстрактным.

МетодToString также является абстрактным. Все наследники обязаны будут его реализовать. Сам же метод будет создавать строку, для записи в файлcsv на основании ключевых полей.

  1. КлассZdanie

Класс описывает тип здание. Фактически здание наследует все поля отPamiatnik и добавляет два поляvisota иadress. В эти поля заносятся высота памятника и адрес памятника. По правилам, данный класс должен определить все виртуальные классы. КлассZdanie знает, как себя отобразить, поэтому реализует метод Draw иToString.

Так как конструкторы не наследуются, то в соответствии с заданием нужно реализовать три конструктора. Один конструктор без параметров, второй с пятью параметрами (значениями для заполнения ключевых полей). Данный конструктор просто делегирует обязанности по заполнению ключевых полей базовому классуPamiatnik.

Третий конструктор – это конструктор, в которую передаётся лишь одна строка в форматеcsv. Данный конструктор будет вызываться во время загрузки данных из файлаcsv. Все данные для одного элемента массива разделяются точкой с запятой. В данном конструкторе входная строка анализируется и раскладывается на ключевые поля.

  1. КлассKvartal

КлассKvartal расширяет базовый класс ещё одним ключевым полем –Ploschad. В данное поле заносится строка, в которой указывается размер площади памятника, который есть в квартале. ПолеPloschadявляетсяprivate, именно поэтому для доступа к нему необходимо создать методset иget.

Также реализуются методыVvod,Draw иToString, а также три конструктора.

  1. КлассSquare

Данный класс ничем не отличается от классаPloschad. В данном классе реализованы все те же поля, что и в предыдущем классеPloschad.

  1. КлассSkulptura

КлассSkulptura расширяет базовый класс ещё одним ключевым полем –Avtor. В данное поле заносится строка, в которой указывается имя автора создавшего скульптуру. ПолеAvtorявляетсяprivate, именно поэтому для доступа к нему необходимо создать методset иget.

Также реализуются методыVvod,Draw иToString, а также три конструктора.

Все классы наследники от классаPamiatnik выводят себя на экран в общую таблицу, т.е. все общие ключевые поля выводятся каждый в свою колонку, а все отличающиеся в поле примечание.

  1. Класс Massiv_Pamiatnikov

Класс оболочка, которая содержит методы для работы с массивом строк. Так как это класс, то для него должен быть хоть один конструктор. В конструкторе нужно будет проинициализировать только два поля, которые содержит данный класс.

Полеfirst предназначено для того, чтобы хранить адрес первого памятника в списке. Благодаря этому полю массив знает, с какого элемента необходимо, например, отображать массив или искать какой-то памятник.  Полеlast предназначено для хранения адреса последнего в массиве памятника. Благодаря этому полю добавление нового элемента в массив осуществляется довольно быстро.

МетодAdd_Pamiatnik(Pamiatnik*p) предназначен для добавления памятника в массив. Для добавления в массив необходимо, чтобы памятник уже был создан, т.е. для него была выделена память. Как уже ранее упоминалось, сам массив не имеет своей памяти для расположения в ней памятников, т.к. класс массива является оболочкой, которая содержит методы для управления массивом. В данный метод достаточно передать адрес любого памятника, и он войдёт в состав динамического массива на последнее место.

МетодDel_Pamiatnik(char*name) предназначен для удаления памятника, точнее данный метод только ищет в массиве адрес памятника, номер которого передан в качестве параметра. И если памятник с указанным номером будет найден, то его адрес передаётся в другую функцию –Del. В функцииDel сначала задаётся уточняющий вопрос о том, нужно ли на самом деле удалять памятник из массива. И если пользователь подтвердит удаление, то запускается механизм удаления. Дело в том, что при удалении всего одного памятника может быть затронуты сразу все памятники. Так как все памятники расположены последовательно, то при удалении второго памятника, необходимо изменить указатели, чтобы первый памятник указывал сразу на третий, а третий на первый. Только после этого можно будет физически удалить памятник.

МетодShowAll предназначен для того, чтобы вызовом одной функции вывести сразу все памятники, зарегистрированные в массиве. В данной функции не только выводятся все памятники, но и все элементы таблицы (шапка таблицы, подчёркивание таблицы).

МетодSaveFile предназначен для сохранения в файл всех памятников, зарегистрированных в массиве. Здесь происходит открытие потока для записи в файл и каждый памятник представив все свои ключевые поля в виде одной строки, записывает в файл.

МетодLoadFile читает памятники из файла. Когда будет прочитана одна очередная строка, содержащая все поля памятников определённого типа, то сначала нужно выделить память для этого памятника, а затем на основании прочитанной строки заполнить все ключевые поля. А лишь затем вызывается метод добавления памятника в массив.

Для создания памятника предназначен специальный метод:

Pamiatnik * Create Pamiatnik (int type,char* stroka)

Главное, что данная функция возвращает указатель на созданный ей памятник. Для того, чтобы функция знала какой конкретный памятник нужно создавать – предназначен параметрtype. Кроме всего прочего в функцию передаётся строка, в которой находятся все ключевые поля для создания памятника.

МетодSort(int pole)  предназначен для сортировки всех памятников в массиве. Причём можно сортировать по разным полям. Для указания поля для сортировки предназначен параметрpole. Сортировка динамического массива производится крайне быстро, так как нет необходимости менять местами большие объёмы памяти, достаточно лишь изменить два поляprev иnextдля каждого из памятников.

Сортировка производится по методу «пузырька», т.е. обмениваются местами рядом стоящие элементы. Однако как ранее упоминалось, нет необходимости физически изменять расположение памятников в памяти. Поэтому при обмене, возможно, потребуется изменить поля сразу 4-х памятников.

МетодFind(char* FindStroka) предназначен для поиска памятника по каким-нибудь данным. При этом не важно, по каким полям нужно искать, так как функция ищет сразу по всем. Дело в том, что мы можем получить все поля в виде одной строки. Именно в этой строке мы и будем искать искомую строкуFindStroka. Можно искать как цифры, так и текст. Все памятники удовлетворяющие критерии поиска выводятся на экран.

МетодStatistika предназначен для вывода статистики по каждому типу памятника в отдельности и для всех сразу. Т.е. памятники группируются по типу и выводятся на экран. После каждой группы выводится статистика по году создания памятника (старый памятник или новый и т.д.). А после того как данные по группам будут выданы – появится общая статистика по всем памятникам.

  1. МодульFunctionFile.cpp

МодульFunctionFile.cpp содержит вспомогательные функции для работы программы.

ФункцияMainMenu предназначена для вывода на экран главного меню, а также для ввода пункта главного меню.

Главное меню состоит из следующих пунктов:

1 - Загрузить памятники из файла csv

2 - Сохранить памятники в файл csv

3 - Просмотреть все памятники

4 - Добавить новый памятник

5 - Удалить памятник

6 - Сортировать памятники

7 - Найти памятник

8 - Групповой отчет

0 - Выход из программы

Если пользователь введёт неверный пункт, то программа сообщит об ошибке и попросит ввести пункт меню заново.

ФункцияMenuTypePamiatnikпредназначена для вывода меню и выбора типа памятника. Например, когда пользователь создаёт памятник, то у него спрашивается, какого типа он желает создать памятник. Данная функция содержит следующие пункты меню:

1 - Здание

2 - Квартал

3 - Площадь

4 - Скульптура

9 - Вернуться в главное меню

Функцияtype_sort выводит меню для выбора поля, по которому нужно будет сортировать массив памятников. Данная функция содержит следующие пункты меню:

1 -  Имя

2 -  Год основания

3 -  Стоимость

9 -  Вернуться в главное меню

ФункцииShowShapkaTabl иShowPodcherkTabl выводят на экран шапку таблицы и подчёркивают таблицу соответственно. Данные функции вызываются из разных мест, поэтому было решено вынести их в отдельные функции.

Функцияchar* GetFileName получает имя файла, например, при сохранении или загрузки файла.

ФункцияShowNameGroup выводит на экран название типов памятников над шапкой таблицы.

  1. Модульmain.cpp

Данный модуль содержит точку входа в программу (методmain). Основная задача методаmain – это управлять всей программой. Принцип управления программой заключается в теории конечных автоматов. Главная идея данного принципа заключается в том, что программа может находиться только в одном состоянии. Например, вывод главного меню, добавление нового элемента – это разные состояния. Каждому состоянию будет соответствовать уникальное число. Также необходима одна переменная (menu) для того, чтобы пользователь мог выбрать пункт меню и его выбор отразился на данной переменной.

Далее показан упрощённый принцип, реализующий принцип конечных автоматов:

Switch(menu)

{

Case 1: // Делаем всё, что касается загрузки данных из файла

Case 2: // делаем действия, чтобы просмотреть все данные

// и так далее

}

Если необходимо какое-то действие детализировать, то мы можем легко добавлять дополнительные пункты меню. Например, если мы выберем пункт меню 6, то у нас программа уточняет, какой конкретно памятник необходимо отсортировать. Теперь все вложенные элементы будут двузначными, например, 61,62 и т.п. И так можно делать вложения достаточно глубоко.

Также в данном модуле  есть функцияCreatePamiatnik, которая вызывается при выборе пункта меню добавления нового памятника. Для создания памятника необходимо указать только тип создаваемого памятника, а данные для памятника должен будет пользователь ввести вручную.

  1. Описание работы программы по контрольному примеру
    1. Описание процесса сортировки памятников

Запускаем программу Kursovoy.exe. Результат отображён на рисунке 3.

Рисунок 3 – Запуск программы

В программе предусмотрено при запуске программы загрузка файла с данными по умолчанию. Данное действие аналогично выбору пункта меню 1 и ввода имени файла с данными.

Выполним пункт 3 для просмотра загруженных данных. Результат представлен на рисунке 4.

Рисунок 4 – Результат просмотра данных

Как видно из рисунка 4 данные не отсортированы не по одному из полей. Поэтому сортировать можно по любому полю. Для продолжения нажимаем клавишу Ввод, затем выбираем пункт меню 6. Результат показан на рисунке 5.

Рисунок 5 – Меню для выбора поля сортировки

Например, сортировать будем по полю «Год основания», поэтому выбираем пункт меню 2. Результат сортировки показан на рисунке 6.

Рисунок 6 – Результат сортировки по полю Год основания

Как видно на рисунке 6 все записи были сортированы по полю «Год основания». Далее достаточно нажать на клавишу Ввод и снова отобразится главное меню.

  1. Описание процесса поиска в массиве памятников

Довольно часто приходится в массиве данных производить поиск. Разработанный программный комплекс позволяет производить поиск в массиве. Для этого необходимо в главном меню (рисунок 3) выбрать пункт меню 7. При этом отобразится строка, в которой нужно будет ввести искомый текст (рисунок 7).

Рисунок 7 – Требование ввести искомую строку

Далее достаточно ввести какой-то ключ для поиска, например, мы введём такую строку: «43». Тогда, учитывая, что первоначально в массиве находятся данные, представленные на рисунке 6, мы получим результат, представленный на рисунке 8.

Рисунок 8 – Результат выполнения поиска строки в массиве

Как видно на рисунке 8, у первого памятника расходы как раз составляют 433000, а у второго памятника год составляет 2043, что также имеет в своей основе 43. Остальные записи не удовлетворяют критериям поиска, поэтому и не были отображены.

  1. Описание формирования статистики по памятникам

Для отображения статистики по памятникам, необходимо чтобы данные уже были загружены в память, т.е. массив существовал. Предполагаем, что у нас загружены исходные данные, отображённые на рисунке 6. Тогда для вывода статистики по памятникам необходимо в главном меню выбрать пункт 8. В результате чего на экране появится статистика по памятникам. Результат вызова статистики по памятникам представлен на рисунке 9.

Рисунок 9 – Вывод статистики по памятникам

Заключение

В процессе курсовой работы разработана программа «Kursovoy.exe».

В программе:

− использованы принципы объектно-ориентированного программирования;

− разработаны различные меню, помогающие пользователю работать с программой;

− описаны классы согласно варианту;

− можно все памятники в м