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

Файл cEllipse.H

class CEllipse : public CCircle

{

int YRad;

public :

CEllipse();

CEllipse(int _X, int _Y, int _XRad, int _YRad);

void SetYRad(int _YRad);

int GetYRad() const;

double GetArea() const;

int getNumType();

void display(std::ostream& x);

virtual ~CEllipse();

};

Файл CEllipse.cpp

class CEllipse : public CCircle

{

int YRad;

public :

CEllipse();

CEllipse(int _X, int _Y, int _XRad, int _YRad);

void SetYRad(int _YRad);

int GetYRad() const;

double GetArea() const;

int getNumType();

void display(std::ostream& x);

virtual ~CEllipse();

};

Файл CText.h

class CText:virtual public ShapePosition

{

std :: string str;

int Height;

int Width;

public:

CText();

CText(int _X , int _Y, std :: string _str);

void SetStr(std :: string _str);

void SetHeight(int _height);

std :: string GetStr() const;

int GetHeight() const;

int getNumType();

void display(std :: ostream &os);

virtual ~CText();

};

Файл СText.cpp

class CText:virtual public ShapePosition

{

std :: string str;

int Height;

int Width;

public:

CText();

CText(int _X , int _Y, std :: string _str);

void SetStr(std :: string _str);

void SetHeight(int _height);

std :: string GetStr() const;

int GetHeight() const;

int getNumType();

void display(std :: ostream &os);

virtual ~CText();

};

Файл с тестовой программой OOT1.cpp

#include "Shape.h"

#include "ShapePosition.h"

#include "CText.h"

#include "CCircle.h"

#include "CEllipse.h"

#include "CEllipseTxT.h"

Shape * obj[4];

obj[0] = new CText("Hello, world!");

obj[1] = new CCircle(0, 0, 100);

obj[2] = new CEllipse(10, 20, 50, 70);

obj[3] = new CEllipseTxt(20, 10, 60, 80, "I am a student");

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

{

cout << obj[i];

cout << endl;

}

return 0;

  • В базовом классе переопределен оператор добавления в поток <<.

В операторе << вызывается виртуальная функция display, изменяющая состояние потока. Эта функция переопределяется во всех наследованных классах, что позволяет каждому классу добавлять в поток свою информацию.

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

  • Просмотрел работу программы по шагам, расставив точки останова. И запустив программу в режиме отладки (Build -> Start Debug -> Go).

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

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

  • Заполняя 3 контейнера строками из <cstring> или другими элементами, продемонстрировать отличия   - последовательностей (vector, list, dequeue);   - адаптеров последовательностей (stack, queue, priority_queue);   - ассоциативных контейнеров на базе map.

  • На примере заполнения одного контейнера-последовательности из предыдущего задания целыми числами, протестировать интерфейсы контейнера и итератора.

  • Аналогично протестировать ассоциативный контейнер, заполняя его указателями на разные графические объекты из разд. 1.1. Протестировать алгоритмы-методы и алгоритмы-классы на множестве графических элементов.

Текст программы, реализующей все вышеперечисленные действия над стандартными контейнерами приведен ниже:

#include "CCircle.h"

#include "CEllipse.h"

#include "CEllipseTxT.h"

#include "CText.h"

#include <iostream>

#include <cstring>

#include <vector>

#include <list>

#include <deque>

#include <stack>

#include <queue>

#include <map>

#include <algorithm>

#include <functional>

class Reverse:public std :: unary_function<Shape* , int>

{

public:

int operator()(Shape * _arg)

{

int rez = _arg->getNumType();

return rez;

}

};

void main()

{

//Заполняем стандартный контейнер vector строками разной длины

//Используя метод контейнера push_back -добаления в конец.

char a = 'a';

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+i));

}

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

{

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

}

std :: cout << std :: endl;

//Заполняем стандартный контейнер list строками разной длины

//используя стандартный итератор библиотеки STL

a = 'z';

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

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

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

{

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

}

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 строками разной длины

//используя методы контейнера push_back и push_front

//для наглядности добавление произодится поочередно в оба конца дека

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

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

a = 'r';

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

{

if (i % 2 == 0)

{

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

}

else

{

de.push_front(std :: string(i + 1,a - i));

}

}

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

{

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

}

std :: cout << std :: endl;

//Заполняем стандартный контейнер 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,'b'));

}

while (!qu.empty())

{

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

qu.pop();

}

std :: cout << std :: endl;

//Заполняем стандартный контейнер 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,'c')));

}

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 указателями на объекты классов

//графических объектов

//используя уникальный целочисленный ключ

std :: cout << "Map with graphic objects: "<< std :: endl;

Shape* cir = new CCircle(0,0,1);

Shape* el = new CEllipse(0,1,2,1);

Shape* text = new CEllipseTxt(9,5, 2, 3,"hello");

Shape* elt = new CText(0,0,"hello 2");

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

Sh_map.insert(std :: pair<int , Shape*>(1 , cir));

Sh_map.insert(std :: pair<int , Shape*>(2 , el));

Sh_map.insert(std :: pair<int , Shape*>(3 , text));

Sh_map.insert(std :: pair<int , Shape*>(4 , elt));

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

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

{

Sh_mit = Sh_map.find(i);

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

}

std :: cout << std :: endl;

//Тестируем алгоритмы-классы на множестве графических объектов

//контейнер Sh_v1 с помощью алгоритма fill заполняется тремя

//указателями CText

//контейнер Sh_v1с помощью алгоритма back_inserter заполняется

//двумя указателями CSquare

std :: cout << "Algorithms: " << std::endl;

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

std :: vector<Shape*> Sh_v2;

std :: vector<Shape*> Sh_v3;

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

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

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;

//тестирование алгоритма-метода

//описание алгоритма-метода Reverse находится перед описанием функции main

//он по заданному указателю на класс объект Shape возвращает номер

//наследованного типа

//Также используется алгоритм-класс transform, который по заданному

//алгоритму-методу Reverse на основе контейнера vmSh1

//заполняет контейнер vmSh2 целочисленными значениями, являющимися номерами типов

std :: cout << "Algorithms-methods: " << std :: endl;

std :: vector<Shape*> vmSh1;

std :: vector<int> vmSh2(5);

vmSh1.push_back(cir);

vmSh1.push_back(el);

vmSh1.push_back(elt);

vmSh1.push_back(text);

std :: transform(vmSh1.begin() , vmSh1.end() , vmSh2.begin() , Reverse());

std :: cout << "First vector: " << std :: endl;

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

{

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

}

std :: cout << "Second vector: " << std :: endl;

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

{

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

}

}

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

  • По индивидуальному заданию контейнер представляет собой граф. Для реализации представляем множество вершин на базе шаблонов list(список номеров вершин) иmap(указатели на вершины)и множество ребер на базе шаблонаmultimap. Номера вершин уникальны. Номером вершины может быть любое целое число. Множество ребер содержит множество пар вершин и для каждой пары значение, указывающее, есть ли ребро между этими вершинами (тогда значение равно 1) или нет (0)

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

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

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

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

    • неправильный запрос элемента в вершине графа (по несуществующему индексу)

    • неправильное добавление вершины или ребра (вершина с уже существующим индексом, ребро, инцидентное несуществующей вершине)

    • неправильное удаление вершины или ребра.

Классы, соответствующие этим ситуациям: GetError,InsertError,DelError.

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

Иерархия классов исключений представлена на рисунке 4.

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

Объявления и реализация контейнеров и итератора приведена ниже, а также тестирующая программа приведены ниже.

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