На рисунке 8 приведена структура и состав файлов проекта в интегрированной среде разработки Visual Studio.NET 2008.
Рис. 8. Структура проекта
Основным файлом проекта является файл POLLY_LAB_№1.cpp., который содержит описание класса Appointment, глобальный динамический массив объектов класса Appointment, функции обработки глобального массива свиданий, точка входа в программу - функция main(), реализующая диалог с пользователем.
//-------------------------------------------------------------------------------------------
// файл POLLY_LAB_№1.cpp
//-------------------------------------------------------------------------------------------
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
//-------------------------------------------------------------------------------------------
// определение класса свидания
class Appointment
{
//-------------------------------------------------------------------
// объявление открытых (публичных) членов класса
public:
// конструктор по умолчанию
Appointment()
{
_name = "";
_surname = "";
_date = "";
|
|
_time = "";
_mark = 0;
}
// конструктор инициализации
Appointment(string name, string surname, string date,
string time, int mark)
{
_name = name;
_surname = surname;
_date = date;
_time = time;
_mark = mark;
}
// конструктор инициализации (без оценочного балла)
Appointment(string name, string surname, string date, string time)
{
_name = name;
_surname = surname;
_date = date;
_time = time;
_mark = 0;
}
// конструктор копирования
// данный конструктор можно не реализовывать явно, тогда
// при создании нового объекта как копии уже существующего,
// по умолчанию происходит присваивание значений полей
// существующего объекта соответствующим полям нового;
// в классе Appointment все поля объявлены системных типов,
// для которых корректно определена операция присваивания;
// таким образом, явная реализация конструктора копирования
// совпадает с реализацией, принятой по умолчанию,
// соответственно, в данном случае является необязательной.
Appointment(const Appointment& app)
{ // всегда принимает ссылку; лучше - константную
_name = app._name;
_surname = app._surname;
|
|
_date = app._date;
_time = app._time;
_mark = app._mark;
}
// деструктор - вызывается в момент уничтожения объекта
// если деструктор не реализовывать явно, то при уничтожении
// объекта автоматически вызовутся деструкторы его полей
~Appointment()
{
_name.~basic_string();
_surname.~basic_string();
_date.~basic_string();
_time.~basic_string();
}
//-------------------------------------------------------------------
// методы для получения значений закрытых полей
string GetName()
{
return _name;
}
string GetSurname()
{
return _surname;
}
string GetDate()
{
return _date;
}
string GetTime()
{
return _time;
}
int GetMark()
{
return _mark;
}
//-------------------------------------------------------------------
// методы для изменения закрытых полей
void SetName(string name)
{
_name = name;
}
void SetSurname(string surname)
{
_surname = surname;
}
void SetDate(string date)
{
_date = date;
}
void SetTime(string time)
{
_time = time;
}
void SetMark(int mark)
{
_mark = mark;
}
//-------------------------------------------------------------------
// объявление закрытых членов класса
private:
string _name; // имя поклонника
string _surname; // фамилия поклонника
string _date,. // дата свидания
string _time; // время свидания
int _mark; // балл по результатам свидания
};
//-------------------------------------------------------------------------------------------
// интерфейсная функция вывода на экран параметров свидания
void PrintAppointment(Appointment app)
{
cout << "Данные свидания..." << endl;
cout << "Имя: " << app.GetName() << endl;
cout << "Фамилия: " << app.GetSurname() << endl;
cout << "Дата: " << app.GetDate() << endl;
cout << "Время: " << app.GetTime() << endl;
cout << "Балл: " << app.GetMark() << endl;
cout << endl;
}
//-------------------------------------------------------------------------------------------
// указатель на динамический массив объектов класса Appointment
Appointment* List = 0;
int count; // размер массива
//-------------------------------------------------------------------------------------------
// функции, реализующие логику предметной области:
// обработку списка свиданий (добавление, удаление, поиск)
// добавление объекта класса Appointment в список;
// функция принимает параметр по значению, соответственно,
// при вызове функции будет создаваться ее локальный объект app,
// который при будет инициализироваться значением фактического
// параметра (то есть при создании локального объекта-параметра
// будет неявно вызываться конструктор копирования)
void Add(Appointment app)
{
// указателю temp присваивается значение указателя,
// хранящего адрес памяти, выделенной под массив свиданий
Appointment* temp = List;
// выделяется память под динамический массив, размерность
// которого превышает размерность текущего массива свиданий
|
|
// на один элемент; адрес выделенной области памяти
// присваивается указателю List
List = new Appointment[++count]; // неявно вызывается
// конструктор по умолчанию (count+1 раз)
// поэлементно копируется старый массив свиданий в новый
for (int i=0;i<count-1;i++)
List[i] = temp[i];
// последнему элементу нового массива свиданий
// присваивается добавляемый объект
List[count-1] = app;
// освобождаем память, занимаемую «старым» массивом
delete[] temp; // неявно вызывается деструктор
} // при выходе неявно вызывается деструктор локального объекта app
//поиск в списке List индекса элемента по дате и времени свидания
int Find(string date, string time)
{
for (int i=0; i < count; i++)
if (List[i].GetDate() == date
&& List[i].GetTime() == time)
return i;
// при отсутствии элемента с заданными параметрами
return -1;
}
// удаление из списка свиданий элемента (по дате и времени)
bool Delete(string date, string time)
{
// если число элементов равно 0, то удалять нечего
if (!count) return false;
// поиск индекса удаляемого элемента (по дате и времени)
int idx = Find(date, time);
// если элемент не найден, то удалять нечего
if (idx == -1) return false;
// указателю temp присваивается значение указателя,
// хранящего адрес памяти, выделенной под массив свиданий
Appointment* temp = List;
// выделяется память под динамический массив, размерность
// которого на один элемент меньше, чем у текущего массива
// свиданий; адрес выделенной области памяти присваивается
// указателю List
List = new Appointment[--count]; // при выделении памяти под
// count-1 ячеек массива
|
|
// неявно вызывается
// конструктор по умолчанию
// (count-1 раз)
// копируются элементы «старого» массива свиданий в
// «новый», начиная с первого и до удаляемого
for (int i = 0; i < idx; i++)
List[i] = temp[i];
// копируются элементы «старого» массива свиданий
// в «новый», начиная с элемента, следующего сразу
// после удаляемого и до последнего
for (int i = idx+1; i < count + 1; i++)
List[i-1] = temp[i];
// освобождается память, занимаемая «старым» масивом
delete[] temp; // при освобождении памяти, занятой массивом
// объектов класса Appointment, для каждого
// элемета неявно вызывается деструктор
// элемент был удален, возвращается «истина»
return true;
}
//-------------------------------------------------------------------------------------------
// функции, реализующие интерфейс взаимодействия с пользователем
// вывод на экран списка поклонников
void PrintList()
{
if (!count)
{
cout<<"Список пуст!"<<endl;
return;
}
else
cout<<"Количество элементов списка: "<< count << endl;
for (int i=0;i<count;i++)
{
cout<<"Свидание № "<<i<<":"<<endl;
PrintAppointment(List[i]);
}
}
// запрос ввода параметров нового свидания
// возвращается новый объект класса Appointment
Appointment InputAppointment()
{
int mark, name, surname, date, time;
cout << "Добавление нового свидания..." << endl;
cout << "Введите имя: ";
cin>>name;
cout << "Введите фамилию: ";
cin>>surname;
cout << "Введите дату: ";
cin>>date;
cout << "Введите время: ";
cin>>time;
cout << "Введите балл: ";
cin>>mark;
// явно вызывается конструктор инициализации
// созданный объект тут же возвращается в качестве
// результирующего значения функции;
// при этом в стеке создается копия возвращаемого объекта,
// для чего неявно вызывается конструктор копирования
return Appointment(name, surname, date, time, mark);
//-------------------------------------------------------------------
// после возврата результирующего значения функции
// неименованный возвращаемый объект уничтожается,
// при этом для него неявно вызывается деструктор
}
// реализация интерфейса взаимодействия с пользователем для
// изменения параметров существующего свидания
void ChangeAppointment()
{
string date, time, temp;
cout<<"\nВведите дату свидания: ";
cin>>date;
cout<<"Введите время свидания: ";
cin>>time;
int select, mark;
int index = Find(date, time);
if (index == -1)
{
cout<<"Данное свидание отсутствует в списке!"<<endl;
return;
}
else
{
cout<<"Что Вы желаете изменить?"<<endl;
cout<<"1 - имя"<<endl;
cout<<"2 - фамилию"<<endl;
cout<<"3 - дату"<<endl;
cout<<"4 - время"<<endl;
cout<<"5 - балл"<<endl;
cout<<"Другое - выход"<<endl;
cout<<"Ваш выбор: ";
cin>>select;
switch (select)
{
case 1:
cout << "Введите имя: ";
cin >> temp;
List[index].SetName(temp);
break;
case 2:
cout<<"Введите фамилию: ";
cin>>temp;
List[index].SetSurname(temp);
break;
case 3:
cout << "Введите дату: ";
cin>>temp;
List[index].SetDate(temp);
break;
case 4:
cout<<"Введите время: ";
cin>>temp;
List[index].SetTime(temp);
break;
case 5:
cout << "Введите балл: ";
cin>>mark;
List[index].SetMark(mark);
break;
default: return;
}
}
}
//-------------------------------------------------------------------------------------------
// главнвя функции – точка входа в программу
// реализует главное меню интерфейса взаимодействия с пользователем
int main()
{
// устанавливается в программе русскоязычная локаль (locale) –
// набор национальных параметров (кодировка символов);
// как результат кириллица в консоли выводится корректно
setlocale(LC_ALL,"Russian");
// объявление локальных переменных
int select; // номер выбранного пункта меню
string date; // строка для представления даты
string time; // строка для представления времени
Appointment app; // вызов конструктора по умолчанию
// явный вызов конструктора инициализации
Appointment first("Ivan", "Ivanov", "2009.7.7", "20:00", 4);
Appointment second("Aleks", "Petrov", "2009.8.1", "21:00", 4);
// при вызове функции добавления объекта класса Appointment
// в глобальный список свиданий неявно вызывается
// конструктор копирования для ее локального параметра
Add(first);
Add(second);
do
{
PrintList();
cout<<"Выбрать действие."<<endl;
cout<<"1. Добавить свидание. "<<endl;
cout<<"2. Удалить свидание. "<<endl;
cout<<"3. Редактировать даннве свидания. "<<endl;
cout<<"Другое - выход"<<endl;
cout<<"Ваш выбор: ";
cin>>select;
switch (select)
{
case 1:
// выполняется оператор присваивания,
// системная реализация которого осуществляет
// копирование значений из полей правого операнда
// в соответствующие поля левого операнда;
// конструктор копирования не вызывается так как
//объект app был создан ранее
app = InputAppointment();
Add(app);
cout<<"Элемент добавлен!"<<endl;
break;
case 2:
cout<<"Введите дату: "; cin>>date;
cout<<"Введите время: "; cin>>time;
if (Delete(date, time))
cout << "Элемент удален!" << endl;
else
cout << "Элемент удалить не удалось!" << endl;
break;
case 3:
ChangeAppointment();
break;
default: return 0;
}
system("pause");
}
while (true);
return 0;
}