Чтение онлайн

на главную - закладки

Жанры

Шрифт:

struct pair (* char* name; int val; *);

class assoc (* pair* vec; int max; int free; public: assoc(int); int amp; operator[](char*); void print_all; *);

В assoc хранится вектор пар pair длины max. Индекс певого неиспользованного элемента вектора находится в free. Конструктор выглядит так:

assoc::assoc(int s) (* max = (s«16) ? s : 16; free = 0; vec = new pair[max]; *)

При реализации применяется все тот же простой и неэффетивный метод поиска, что использовался в #2.3.10. Однако при переполнении assoc увеличивается:

#include «string.h»

int assoc::operator[](char* p) /* работа с множеством пар «pair»: поиск p, возврат ссылки на целую часть его «pair» делает новую «pair», если p не встречалось */ (* register pair* pp;

for (pp= amp;vec[free-1]; vec«=pp; pp–) if (strcmp(p,pp-»name)==0) return pp-»val;

if (free==max) (* // переполнение: вектор увеличивается

pair* nvec = new pair[max*2]; for ( int i=0; i«max; i++) nvec[i] = vec[i]; delete vec; vec = nvec; max = 2*max; *)

pp = amp;vec[free++]; pp-»name = new char[strlen(p)+1]; strcpy(pp-»name,p); pp-»val = 0; // начальное значение: 0 return pp-»val; *)

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

vouid assoc::print_all (* for (int i = 0; i«free; i++) cout „« vec[i].name «« ": " «« vec[i].val «« «\n“; *)

Мы можем, наконец, написать простую главную программу:

main // считает вхождения каждого слова во вводе (* const MAX = 256; // больше самого большого слова char buf[MAX]; assoc vec(512); while (cin»»buf) vec[buf]++; vec.print_all; *)

6.8 Вызов функции

Вызов функции, то есть запись выражение(список_выражний), можно проинтерпретировать как бинарную операцию, и операцию вызова можно перегружать так же, как и другие оперции. Список параметров функции operator вычисляется и прверяется в соответствие с обычными правилами передачи парметров. Перегружающая функция может оказаться полезной главным образом для определения типов с единственной операцей и для типов, у которых одна операция настолько преобладет, что другие в большинстве ситуаций можно не принимать во внимание.

Для типа ассоциативного массива assoc мы не определили итератор. Это можно сделать, определив класс assoc_iterator, работа которого состоит в том, чтобы в определенном порядке поставлять элементы из assoc. Итератору нужен доступ к даным, которые хранятся в assoc, поэтому он сделан другом:

class assoc (* friend class assoc_iterator; pair* vec; int max; int free; public: assoc(int); int amp; operator[](char*); *);

Итератор определяется как

class assoc_iterator(* assoc* cs; // текущий массив assoc int i; // текущий индекс public: assoc_iterator(assoc amp; s) (* cs = amp;s; i = 0; *) pair* operator (* return (i«cs-»free)? amp;cs-»vec[i++] : 0; *) *);

Надо инициализировать assoc_iterator для массива assoc, после чего он будет возвращать указатель на новую pair из этого массива всякий раз, когда его будут активизировать опрацией . По достижении конца массива он возвращает 0:

main // считает вхождения каждого слова во вводе (* const MAX = 256; // больше самого большого слова char buf[MAX]; assoc vec(512); while (cin»»buf) vec[buf]++; assoc_iterator next(vec); pair* p; while ( p = next ) cout «„ p-“name „„ ": " «« p-“val «« «\n“; *)

0 Итераторный тип вроде этого имеет преимущество перед нбором функций, которые выполняют ту же работу: у него есть собственные закрытые данные для хранения хода итерации. К тму же обычно существенно, чтобы одновременно могли работать много итераторов этого типа.

Конечно, такое применение объектов для представления итераторов никак особенно с перегрузкой операций не связано. Многие любят использовать итераторы с такими операциями, как first, next и last (первый, следующий и последний).

6.9 Класс String

Вот довольно реалистичный пример класса строк string. В нем производится учет ссылок на строку с целью минимизировать копирование и в качестве констант применяются стандартные символьные строки С++.

#include «stream.h» #include «string.h»

class string (* struct srep (* char* s; // указатель на данные int n; // счетчик ссылок *); srep *p;

public: string(char *); // string x = «abc» string; // string x; string(string amp;); // string x = string ... string amp; operator=(char *); string amp; operator=(string amp;); ~string; char amp; operator[](int i);

friend ostream amp; operator«„(ostream amp;, string amp;); friend istream amp; operator“»(istream amp;, string amp;);

friend int operator==(string amp; x, char* s) (*return strcmp(x.p-»s, s) == 0; *)

friend int operator==(string amp; x, string amp; y) (*return strcmp(x.p-»s, y.p-»s) == 0; *)

friend int operator!=(string amp; x, char* s) (*return strcmp(x.p-»s, s) != 0; *)

friend int operator!=(string amp; x, string amp; y) (*return strcmp(x.p-»s, y.p-»s) != 0; *)

*);

Конструкторы и деструкторы просты (как обычно):

string::string (* p = new srep; p-»s = 0; p-»n = 1; *)

string::string(char* s) (* p = new srep; p-»s = new char[ strlen(s)+1 ]; strcpy(p-»s, s); p-»n = 1; *)

string::string(string amp; x) (* x.p-»n++; p = x.p; *)

string::~string (* if (–p-»n == 0) (* delete p-»s; delete p; *) *)

Как обычно, операции присваивания очень похожи на контрукторы. Они должны обрабатывать очистку своего первого (лвого) операнда:

string amp; string::operator=(char* s) (* if (p-»n » 1) (* // разъединить себя p-»n–; p = new srep; *) else if (p-»n == 1) delete p-»s;

Поделиться:
Популярные книги

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Романов. Том 1 и Том 2

Кощеев Владимир
1. Романов
Фантастика:
фэнтези
попаданцы
альтернативная история
5.25
рейтинг книги
Романов. Том 1 и Том 2

Телохранитель Генсека. Том 3

Алмазный Петр
3. Медведев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Телохранитель Генсека. Том 3

Герой

Бубела Олег Николаевич
4. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Герой

Московское золото и нежная попа комсомолки. Часть Пятая

Хренов Алексей
5. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото и нежная попа комсомолки. Часть Пятая

Волчье солнышко (Сборник)

Бушков Александр Александрович
Фантастика:
научная фантастика
5.25
рейтинг книги
Волчье солнышко (Сборник)

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Точка Бифуркации

Смит Дейлор
1. ТБ
Фантастика:
боевая фантастика
7.33
рейтинг книги
Точка Бифуркации

Третье правило диверсанта

Бычков Михаил Владимирович
Фантастика:
постапокалипсис
5.67
рейтинг книги
Третье правило диверсанта

Бастард Императора. Том 10

Орлов Андрей Юрьевич
10. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
6.25
рейтинг книги
Бастард Императора. Том 10

Черный Маг Императора 16

Герда Александр
16. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 16

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Законы рода

Мельник Андрей
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Законы рода