Скачиваний:
11
Добавлен:
01.05.2014
Размер:
123.39 Кб
Скачать

Санкт-Петербургский Государственный Электротехнический Университет им.Ульянова (Ленина)

«ЛЭТИ»

каф. МОЭВМ

Лабораторная работа №1

«Программирование контейнерных классов»

Вариант 1 и 15

Выполнила

Студентка гр. 3341

Филиппова К.С.

Проверил

доц. Спицин А.В.

2007

1. Разработка программ в среде MS Visual C++.

1.1. Настройка среды. Выполнение индивидуального задания.

Задание:

  1. Найти проекты MFC Tutorial. Откомпилировать и выполнить пример TrialRun.

  2. Написать классы для создания графических объектов. Классы должны иметь общий абстрактный базовый класс Shape с чистыми виртуальными функциями.

Реализуемые классы: квадрат, прямоугольник, текст, текст в прямоугольнике.Необходимо использовать множественное наследование. В классах должны быть предусмотрены виртуальные функции для вывода информации об объектах в поток, а Shape должен иметь дружественный перегруженный оператор <<.

Исходный текст должен быть разделен на три файла .h, .cpp и .cpp с тестовой программой.

Реализация:

  1. Загрузив проект MSF Tutorial, и выполнив его ознакомились с настройками среды программирования MS Visual C++ для написания проекта консольного win32 приложения.

  1. При реализации поставленной задачи было создано 5 классов:

Класс kvadrat

Задает параметры фигуры квадрат по значению координат одной из вершины (x и y) и длине стороны (a). Наследник класса Shape.

Входные данные

Выходные данные

Описание

Атрибуты

Int X

Координата X вершины

Int Y

Координата Y вершины

Int A

Длина стороны

Методы

getX()

-

Int

Получение атрибута X

getY()

-

Int

Получение атрибута Y

getA()

-

Int

Получение атрибута А

Draw()

-

-

Прорисовка объекта

Print

-

-

Вывод в поток

Move

Double double

-

Сдвиг

Класс priam

Задает параметры фигуры прямоугольник по значению координат одной из вершины (x и y) и длине двух стороны (a и b). Наследник класса Shape.

Входные данные

Выходные данные

Описание

Атрибуты

Int X

Координата X вершины

Int Y

Координата Y вершины

Int A

Длина стороны A

Int B

Длина стороны B

Методы

getX()

-

Int

Получение атрибута X

getY()

-

Int

Получение атрибута Y

getA()

-

Int

Получение атрибута А

getB()

int

Получение атрибута B

Draw()

-

-

Прорисовка объекта

Print

-

-

Вывод в поток

Move

Double Double

-

Сдвиг

Класс Text

Задает параметры фигуры текст по значению координат расположения текста и самого его значения. Наследник класса Shape.

Входные данные

Выходные данные

Описание

Атрибуты

Int K

Координата X вершины

Int Z

Координата Y вершины

char ST

Сам текст

Методы

getK()

-

Int

Получение атрибута K

getZ()

-

Int

Получение атрибута Z

getST()

-

char

Получение атрибута ST

Draw()

-

-

Прорисовка объекта

Print()

-

-

Вывод в стандартный поток

Класс text_in_priam

Задает параметры фигуры текст в прямоугольнике. Все атрибуты и метды наследуются из базовых классов Text и Priam.

Входные данные

Выходные данные

Описание

Draw()

-

-

Прорисовка объекта

Класс Shape

Является абстрактным классом с абстрактным методом и дружественным перегруженным оператором вывода в поток (<<). Этот класс является интерфейсным для производных классов.

Входные данные

Выходные данные

Описание

Draw()

-

-

Прорисовка объекта

Operator <<

Вывод в поток

Изображения классов и отношений генерализации в UML в приложении.

1.2. Работа в режиме отладки.

Запустить программу и просмотреть ее работу по шагам (Build -> Start Debug -> Go)

Просмотрим иерархию классов. В окне дебаггера появляются текущие т.е. обрабатываемые в данный момент объекты и переменные. Здесь можно просмотреть их структуру.

Из рисунка видно, какую структуру имеет каждый объект и по какому адресу памяти находиться. Например, переменная KV3 класса Text_in_priam имеет сложную стуктуру множественнго наследования.

Расставим точки превывания программы (Break Points) и её работу. Для выяснения текущих значений переменных, использовать механизм "Watch variable".

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

 1.3. Исследование программы при помощи Profiler.

2. Применение стандартной библиотеки STL

2.1. Составить консольные приложения, демонстрирующие основные операции с контейнерами и итераторами STL.

Заполняя 3 контейнера строками из <cstring> или другими элементами, продемонстрировать отличия   - последовательностей (vector, list, dequeue);

// контейнер vector

std::cout<<"Vector: "<<std::endl;

std::vector<std::string> v;

for (int i=0;i<5;i++)

{v.push_back(std::string(i+1,'a'));

}

for (i=0;i<v.size();i++)

{std::cout<<v[i]<<std::endl;

}

std::cout<<std::endl;

// контейнер list

std::cout<<"List: "<<std::endl;

std::list<std::string> l;

for (i=0;i<5;i++)

{l.push_back(std::string(i+1,'a'));

}

std::list<std::string>::iterator lp;

while (!l.empty())

{ lp=l.begin();

std::cout<<*lp<<std::endl;

l.pop_front();

}

std::cout<<std::endl;

// контейнер deque

std::cout<<"Deque: "<<std::endl;

std::deque<std::string> de;

for (i=0;i<5;i++)

{

if (i%2==0)

{de.push_back(std::string(i+1,'a'));}

else

{de.push_front(std::string(i+1,'a'));}

}

for (i=0;i<de.size();i++)

{

std::cout<<de[i]<<std::endl;

}

std::cout<<std::endl;

  - адаптеров последовательностей (stack, queue);

// контейнер stack

std::cout<<"Stack: "<<std::endl;

std::stack<std::string,std::vector<std::string> > st;

for (i=0;i<5;i++)

{

st.push(std::string(i+1,'a'));

}

while (!st.empty())

{

std::cout<<st.top()<<std::endl;

st.pop();

}

std::cout<<std::endl;

// контейнер queue

std::cout<<"Queue: "<<std::endl;

std::queue<std::string,std::list<std::string> > qu;

for (i=0;i<5;i++)

{

qu.push(std::string(i+1,'a'));

}

while (!qu.empty())

{

std::cout<<qu.front()<<std::endl;

qu.pop();

}

std::cout<<std::endl;

- ассоциативных контейнеров на базе map.

//контейнер map

std::cout<<"Map: "<<std::endl;

std::map<int,std::string> m;

for(i=0;i<10;i++)

{

m.insert(std::pair<int,std::string>(i,std::string(i+1,'a')));

}

std::map<int,std::string>::iterator mit;

for (i=0;i<m.size();i++)

{

mit=m.find(i);

std::cout<<mit->second<<std::endl;

}

std::cout<<std::endl;

// контейнер map

double points1[4][2]={{1,1},{1,2},{2,1},{2,2}};

double points2[4][2]={{1,1},{1,4},{3,1},{3,4}};

shape* KV =new kvadrat(points1);

shape* PR =new priam(points2);

shape* TX =new text("bla-la",5,8);

shape* TXPR =new text_in_priam(points1,"BLA-LA");

std::map<int,shape*> Sh_map;

Sh_map.insert(std::pair<int,shape*>(1,KV));

Sh_map.insert(std::pair<int,shape*>(2,PR));

Sh_map.insert(std::pair<int,shape*>(3,TX));

Sh_map.insert(std::pair<int,shape*>(4,TXPR));

std::map<int,shape*>::iterator Sh_mit;

for (i=1;i<Sh_map.size()+1;i++)

{

Sh_mit=Sh_map.find(i);

cout<<(Sh_mit->second)<<endl<<endl;

}

std::cout<<std::endl;

  • Аналогично протестировать ассоциативный контейнер, заполняя его указателями

на разные графические объекты из разд. 1.1. Протестировать алгоритны-методы и алгоритмы-классы на множестве графических элементов.

// тестирование контейнера vector на объектах класса shape

std::vector<shape*> Sh_v1(3);

std::vector<shape*> Sh_v2;

std::vector<shape*> Sh_v3;

std::fill(Sh_v1.begin(),Sh_v1.end(),KV);

std::fill_n(std::back_inserter(Sh_v2),2,PR);

std::cout<<"Fill: "<<std::endl;

for(i=0;i<Sh_v1.size();i++)

{std::cout<<Sh_v1[i]<<std::endl<<std::endl;}

std::cout<<std::endl<<std::endl;

std::cout<<"Fill vs inserter: "<<std::endl;

for(i=0;i<Sh_v2.size();i++)

{std::cout<<Sh_v2[i]<<std::endl<<std::endl;}

std::cout<<std::endl<<std::endl;

}

2.2. Реализовать новый шаблон контейнера и шаблон итератора для него по индивидуальному заданию.

  • По индивидуальному заданию контейнер представляет собой множество на базе списка.

Множество реализовано на базе стандартного контейнера List стандартной библиотеки языка MS Visual C++.

Дополнительные возможности контейнера это объединение 2-х контейнеров (функция Edin) и исключение (функция iskl ). Эти функции отражают соответствующие операции над множеством.

Диаграмма классов контейнеров приведена на рисунке 2.

  • Класс итератор для контейнера-множества является внешним итератором и использует функции контейнера. В качестве одного из аргументов содержит ссылку на класс списка, что исключает приведение типов и использование итератора не для того контейнера, а так же номер элемента списка, на которой ссылается итенатор.

  • Обработка исключительных ситуаций.

В программе обрабатываются один вид исключительных ситуаций: запрос несуществующего значения. Другие ошибки по сути повторяют первую.

Класс, соответствующий этой ситуации - ErInd.

При возникновении исключительной ситуации, генерируется исключительная ситуация соответствующего типа, которая перехватывается в тестирующей программе.

  • Контейнер тестируется на графических объектах. Заполняя и удаляя объекты из контейнера:

// задается класс Shape

shape* KV =new kvadrat(points1);

shape* PR =new priam(points2);

shape* TX =new text("bla-la",5,8);

shape* TXPR =new text_in_priam(points1,"BLA-LA");

//создается контейнер множества

LSet<shape *> ls1;

SetIterator<shape *> it1(ls1);

LSet<shape *> ls2;

LSet<shape *> ls3;

//заполняется контейнер множества

ls1.InsertEl(KV);

ls1.InsertEl(PR);

ls1.InsertEl(TX);

ls1.InsertEl(TXPR);

// выводиться содержимое контейнера в поток

cout<<"List 2:"<<endl;

cout<<ls1;

ls2=edin(ls1,ls);

// дополнительные функции

cout<<"List 3 OB'EDINENIE"<<endl;

cout<<ls2;

ls3=iskl(ls2, ls);

ls.dellete(20);

ls1.getElem(22);

Соседние файлы в папке Лабораторная работа 14