Читаем C++ полностью

<p>6.7 Индексирование</p>

Чтобы задать смысл индексов для объектов класса, исползуется функция operator[]. Второй параметр (индекс) функции operator[] может быть любого типа. Это позволяет определять ассоциативные массивы и т.п. В качестве примера давайте перпишем пример из #2.3.10, где при написании небольшой програмы для подсчета числа вхождений слов в файле применялся ассциативный массив. Там использовалась функция. Здесь определяется надлежащий тип ассоциативного массива:

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; *)

<p>6.8 Вызов функции</p>

Вызов функции, то есть запись выражение(список_выражний), можно проинтерпретировать как бинарную операцию, и операцию вызова можно перегружать так же, как и другие оперции. Список параметров функции 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 (первый, следующий и последний).

<p>6.9 Класс String</p>

Вот довольно реалистичный пример класса строк 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;);

Перейти на страницу:

Похожие книги

Основы программирования в Linux
Основы программирования в Linux

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым. Для начинающих Linux-программистов

Нейл Мэтью , Ричард Стоунс , Татьяна Коротяева

ОС и Сети / Программирование / Книги по IT
97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT
Программист-прагматик. Путь от подмастерья к мастеру
Программист-прагматик. Путь от подмастерья к мастеру

Находясь на переднем крае программирования, книга "Программист-прагматик. Путь от подмастерья к мастеру" абстрагируется от всевозрастающей специализации и технических тонкостей разработки программ на современном уровне, чтобы исследовать суть процесса – требования к работоспособной и поддерживаемой программе, приводящей пользователей в восторг. Книга охватывает различные темы – от личной ответственности и карьерного роста до архитектурных методик, придающих программам гибкость и простоту в адаптации и повторном использовании.Прочитав эту книгу, вы научитесь:Бороться с недостатками программного обеспечения;Избегать ловушек, связанных с дублированием знания;Создавать гибкие, динамичные и адаптируемые программы;Избегать программирования в расчете на совпадение;Защищать вашу программу при помощи контрактов, утверждений и исключений;Собирать реальные требования;Осуществлять безжалостное и эффективное тестирование;Приводить в восторг ваших пользователей;Формировать команды из программистов-прагматиков и с помощью автоматизации делать ваши разработки более точными.

А. Алексашин , Дэвид Томас , Эндрю Хант

Программирование / Книги по IT