є розподільники пам'яті, предикати і функції порівняння.
У кожного контейнера є визначений для нього розподільник пам'яті (allocator), що керує процесом виділення пам'яті для контейнера.
За замовчуванням розподільником пам'яті є об'єкт класу allocator. Можна визначити власний розподільник.
У деяких алгоритмах і контейнерах використовується функція особливого типу, що називається предикатом. Предикат може бути унарним і бінарним. Значення, що повертається: істина або неправда. Точні умови одержання того чи іншого значення визначаються програмістом. Тип унарних предикатів UnPred, бінарних – BinPred. Тип аргументів відповідає типу об'єктів, що зберігаються в контейнері.
Визначено спеціальний тип бінарного предиката для порівняння двох елементів. Він називається функцією порівняння (comparison function). Функція повертає істину, якщо перший елемент менше другого. Типом функції є тип Comp.
Особливу роль у STL грають об'єкти-функції.
Об'єкти-функції - це екземпляри класу, у якому визначена операція “круглі дужки” (). У ряді випадків зручно замінити функцію на об'єкт - функцію. Коли об'єкт – функція використовується як функцію, то для її виклику використовується operatot().
1.3. Класи-контейнери, як засоби організації колекцій елементів.
У STL визначені два типи контейнерів – послідовності й асоціативні контейнери.
Для стандартних контейнерів полягає в тім, що коли це представляється розумним, вони повинні бути логічно взаємозамінними. Користувач може вибирати між ними, ґрунтуючись на розуміннях ефективності і потреби в спеціалізованих операціях. Наприклад, якщо часто потрібен пошук по ключі. можна скористатися map (асоціативним масивом). З іншого боку, якщо переважають операції, характерні для списків, можна скористатися контейнером list. Якщо додавання і видалення елементів часто виконується в кінці контейнера, варто подумати про використання черги queue, черги з двома кінцями deque, стека stack. За замовчуванням користувач повинний використовувати vector; він реалізований, щоб добре працювати для самого широкого діапазону задач.
Ідея звертання з різними видами контейнерів – і, у загальному випадку, із усіма видами джерел інформації – уніфікованим способом, веде до поняття узагальненого програмування. Для підтримки цієї ідеї STL містить множину узагальнених алгоритмів. Такі алгоритми рятують програміста від необхідності знати подробиці окремих контейнерів.
У STL визначені наступні класи-контейнери(у кутових дужках зазначені заголовні файли, де визначені ці класи):
bitset множину бітів <bitset.h>
vector динамічний масив <vector.h>
list лінійний список <list.h>
deque двостороння черга <deque.h>
stack стек <stack.h>
queue черга <queue.h>
priority_queue черга з пріоритетом <queue.h>
map асоціативний список для збереження пар ключ/значення, де з кожним ключем зв'язане одне значення <map.h>
multimap з кожним ключем зв'язано два чи більше значення <map.h>
set множина <set.h>
multiset множина, у якій кожен елемент не обов'язково унікальний <set.h>
2. Розробка класу у середовищі Microsoft Visual С++
2.1. Представлення класів, як діаграм UML
Рисунок 2.1. — Діаграма класів UML
UML (Unified Modeling Language) - уніфікована мова об'єктно-орієнтованого моделювання, використовується у парадигмі об'єктно-орієнтованого програмування. Є невід'ємною частиною уніфікованого процесу розробки програмного забезпечення.
UML може бути застосована на всіх етапах життєвого циклу аналізу бізнес-систем і розробки додатків. Різні види діаграм які підтримуються UML, і найбагатший набір можливостей представлення певних аспектів системи робить UML універсальним засобом опису як програмних, так і ділових систем.
2.2. Лістинги файлів проекту ProceedSTL
Лістинг 1. Файл ProceadSTL.h — Інтерфейс класу ProceedSTL
#pragma once
#include <vector>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <strstream>
#include <exception>
using namespace std;
template <class _type1, class _type2>
class ProceadSTL
{
public:
ProceadSTL(void);
ProceadSTL(size_t size);
ProceadSTL(const ProceadSTL& rhs);
~ProceadSTL(void);
_type1& getFromVek1(size_t index);
_type2& getFromVek2(size_t index);
_type1& getFromMatrix1(size_t x, size_t y);
_type2& getFromMatrix2(size_t x, size_t y);
size_t getSize()const;
void ResizeVek1(size_t size);
void ResizeVek2(size_t size);
void setMatrix1Size(size_t x, size_t y);
void setMatrix2Size(size_t x, size_t y);
void SortVek1();
void SortVek2();
void MergeVek1Vek2();
void SortMatrix1();
void SortMatrix2();
void MergeMatrix12();
void Clear();
void ClearMatrix();
bool operator == (const ProceadSTL<_type1, _type2>& rhs);
bool operator != (const ProceadSTL<_type1, _type2>& rhs);
bool operator < (const ProceadSTL<_type1, _type2>& rhs);
bool operator <= (const ProceadSTL<_type1, _type2>& rhs);
bool operator > (const ProceadSTL<_type1, _type2>& rhs);
bool operator >= (const ProceadSTL<_type1, _type2>& rhs);
friend ostream & operator << <_type1, _type2>(ostream & output, const ProceadSTL<_type1, _type2> & pstl);
friend istream & operator >> <_type1, _type2>(istream & input, ProceadSTL<_type1, _type2> & pstl);
private:
size_t m_size;
std::vector<_type1> m_vek1;
std::vector<_type2> m_vek2;
std::vector<vector<_type1>> m_matrix1;
std::vector<vector<_type2>> m_matrix2;
};
Лістинг 2. Файл ProceadSTL.cpp — Реалізація класу ProceedSTL
#include "StdAfx.h"
#include "ProceadSTL.h"
template <class _type1, class _type2>
ProceadSTL<_type1, _type2>::ProceadSTL(void)
{
m_size = 0;
}
template <class _type1, class _type2>
ProceadSTL<_type1, _type2>::ProceadSTL(size_t size)
{
m_size = size;
m_vek1.resize(size);
m_vek2.resize(size);
m_matrix1.resize(size);
for (size_t i = 0; i < size; i++)
{
m_matrix1[i].resize(size);
}
m_matrix2.resize(size);
for (size_t i = 0; i < size; i++)
{
m_matrix2[i].resize(size);
}
}
template <class _type1, class _type2>
ProceadSTL<_type1, _type2>::ProceadSTL(const ProceadSTL& rhs)
{
m_size = rhs.m_size;
m_vek1.clear();
m_vek2.clear();
m_matrix1.clear();
m_matrix2.clear();
m_vek1.insert(m_vek1.begin(), rhs.m_vek1.begin(), rhs.m_vek1.end());
m_vek2.insert(m_vek2.begin(), rhs.m_vek2.begin(), rhs.m_vek2.end());
m_matrix1.insert(m_matrix1.begin(), rhs.m_matrix1.begin(), rhs.m_matrix1.end());
m_matrix1.insert(m_matrix2.begin(), rhs.m_matrix2.begin(), rhs.m_matrix2.end());
}
template <class _type1, class _type2>
ProceadSTL<_type1, _type2>::~ProceadSTL(void)
{
m_vek1.clear();
m_vek2.clear();
m_matrix1.clear();
m_matrix1.clear();
}
template <class _type1, class _type2>
_type1& ProceadSTL<_type1, _type2>::getFromVek1(size_t index)
{
if (index >=0 && index < m_vek1.size())
{
return *(m_vek1.begin() + index);
}
else
{
throw exception("Item index out of bound");
}
}
template <class _type1, class _type2>
_type2& ProceadSTL<_type1, _type2>::getFromVek2(size_t index)
{
if (index >=0 && index < m_vek2.size())
{
return *(m_vek2.begin() + index);
}
else
{
throw exception("Item index out of bound");
}
}
template <class _type1, class _type2>
_type1& ProceadSTL<_type1, _type2>::getFromMatrix1(size_t x, size_t y)
{
if (x >=0 && x < m_matrix1.size() && y >= 0 && y < m_matrix1[x].size())
{
return m_matrix1[x][y];
}
else
{
throw exception("Item index out of bound");
}
}
template <class _type1, class _type2>
_type2& ProceadSTL<_type1, _type2>::getFromMatrix2(size_t x, size_t y)
{
if (x >=0 && x < m_matrix2.size() && y >= 0 && y < m_matrix2[x].size())
{
return m_matrix2[x][y];
}
else
{
throw exception("Item index out of bound");
}
}
template <class _type1, class _type2>
size_t ProceadSTL<_type1, _type2>::getSize()const
{
return m_size;
}
template <class _type1, class _type2>
void ProceadSTL<_type1, _type2>::ResizeVek1(size_t size)
{
m_vek1.resize(size);
}
template <class _type1, class _type2>
void ProceadSTL<_type1, _type2>::ResizeVek2(size_t size)
{
m_vek2.resize(size);
}
template <class _type1, class _type2>
void ProceadSTL<_type1, _type2>::Clear()
{
m_vek1.clear();
m_vek2.clear();
m_matrix1.clear();
m_matrix2.clear();
}
template <class _type1, class _type2>
void ProceadSTL<_type1, _type2>::ClearMatrix()
{
m_matrix1.clear();
m_matrix2.clear();
}
template <class _type1, class _type2>
void ProceadSTL<_type1, _type2>::setMatrix1Size(size_t x, size_t y)
{
m_matrix1.clear();
m_matrix1.resize(x);
for (size_t i = 0; i < m_matrix1.size() ; i++ )
{
m_matrix1[i].clear();
m_matrix1[i].resize(y);
}
}
template <class _type1, class _type2>
void ProceadSTL<_type1, _type2>::setMatrix2Size(size_t x, size_t y)
{
m_matrix2.clear();
m_matrix2.resize(x);
for (size_t i = 0; i < m_matrix2.size() ; i++ )
{
m_matrix2[i].clear();
m_matrix2[i].resize(y);
}
}
template <class _type1, class