T2 second;
Tl first;
Словари
Yes
Ben B i l l Jessica John Mary Monica Sju
B i l l Monica
B i l l John Monica Sju
Ben Bin Jessica Mary Monica
В определении класса mар используется тип pair, который описан в заголовочном файле <utility> следующим образом:
template <class Tl, class Т2> struct pair{
pair(const T1& X. const T2& y);
Шаблон pair имеет два параметра, представляющих собой типы элементов пары.
Первый элемент пары имеет имя first, второй — second.
В этом же файле определены шаблонные операции ==,!=, <, >, <=, >= для двух объектов типа pair.
Шаблон словаря имеет три параметра: тип ключа, тип элемента и тип функционального объекта, определяющего отношение «меньше»:
template <class Key, class Т, class Compare = less<Key> >
class map {
public:
typedef pair <const Key, T> value_type;
explicit map(const Compare& comp = Compare());
map(const value_type* fist, const value_type* last,
const Compare& comp = Compare());
map (const map <Key, T, Compare> & x);
Обратите внимание на то, что тип элементов словаря value_type определяется как пара элементов типа Key и Т.
Первый конструктор класса тар создает пустой словарь.
|
|
Второй — создает словарь и записывает в него элементы, определяемые диапазоном [first, last).
Третий конструктор является конструктором копирования.
Для доступа к элементам по ключу определена операция []:
Т& operator[](const Key & х);
С помощью нее можно не только получать значения элементов, но и добавлять в словарь новые.
Для использования контейнеров типа тар необходимо подключить заголовочный файл <тар>.
В конце темы рассмотрим построение простейшего последовательного контейнера, элементы которого объединены в список. Класс итератора мог быть определен как локальный, но мог быть и дружественным. Рассмотрим последний случай.
Для простоты каждый узел списка представим объектом класса (узел связанного списка для контейнера строк):
//liststr.h
class node {
node* next;
string str;
friend class list_str;
friend class list_iter;
}
//определение класса итератора
class{
node* current; //указатель на текущий элемент списка
public:
list_iter(node* new_node=0):current(new_node)
{ }
string & operator* () //разыменование итератора
{
return current->str;
}
list_iter& operator++() // инкремент
{current = current->next;
return *this;
}
bool operator!=(list_iter other) { //сравнение итераторов
return (other.current!= current);
}
bool operator==(list_iter other) { //сравнение итераторов
return (other. current == current);
}
};
В классе закрытый компонент – указатель current на объект класса node, представляющий элемент (узел) списка.
В конструкторе current присваивается адрес узла списка или 0 по умолчанию.
Базовые операции для итераторов реализованы как операции – функции.
Используя классы node и list_iter, определим контейнер в виде односвязаного списка
class liststr {
node * beg_node; // первый элемент
node * end_node; // последний элемент
|
|
public:
liststr (string&st); // конструктор
void append(string&st); // добавить элемент в конец списка
~liststr(); // деструктор
list_iter begin() // начало списка
{return list_iter(beg_node);}
list_iter end() // конец списка, вернуть ссылку на пустой элемент
{return list_iter(end_node)->next;}
};
//===========================
lister::liststr (string&st){
node * temp=new node;
temp->next=0;
temp->str=st;
beg_node=temp;
end_node=temp;
}
//======================
void lister:: append(string&newStr) {
node * temp=new node;
temp->next=0;
temp->str=newStr;
end_node-> next=temp;
end_node=temp;
}
//==================================
//Print.h
template <class Т>
void Print(T beg, T end) {
int i=0;
while(beg!=end)
{cout<<”[“<<i++<<”]”<<*beg<<”\t”;
++beg;}
cout << endl;
}
//==============================
#include <iostream>
using namespace std;
#include ”liststr.h”
#include “Print.h”
int main() {
string num=”12345”;
liststr spisok(num);
string abc(“abcde”);
spisok.append(abc);
abc=”word”;
spisok.append(abc);
Print(spisok.begin(), spisok.end());
}
Результат:
/*
list_iter it=spisok.begin();
cout<<*it<<endl;
++it;
cout<<*it<<endl;…
Результат:
abcde*/