![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
#include
int assoc::operator[](char* p)
/*
работа с множеством пар "pair":
поиск p,
возврат ссылки на целую часть его "pair"
делает новую "pair", если p не встречалось
*/
{
register pair* pp;
for (pp = &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; iname = new char [strlen(p)+1];i++);
strcpy(pp->name,p);
pp->val = 0; // начальное значение: 0
return pp->val;
}
Поскольку представление assoc скрыто, нужен способ его печати. Здесь воспользуемся простой функцией печати:
vouid assoc::print_all()
{
for (int i = 0; i>buf) vec[buf]++;
vec.print_all();
}
Вызов Функции. Вызов функции, то есть запись выражение(список_выражений), можно проинтерпретировать как бинарную операцию, и операцию вызова можно перегружать так же, как и другие операции. Список параметров функции operator() вычисляется и проверяется в соответствие с обычными правилами передачи параметров. Перегружающая функция может оказаться полезной главным образом для определения типов с единственной операцией и для типов, у которых одна операция настолько преобладает, что другие в большинстве ситуаций можно не принимать во внимание.
Для типа ассоциативного массива assoc мы не определили итератор. Это можно сделать, определив класс assoc_iterator, работа которого состоит в том, чтобы в определенном порядке поставлять элементы из assoc. Итератору нужен доступ к данным, которые хранятся в assoc, поэтому он сделан другом:
class assoc
{
friend class assoc_iterator;
pair* vec;
int max;
int free;
public:
assoc(int);
int& operator[](char*);
};
Итератор определяется как
class assoc_iterator
{
assoc* cs; // текущий массив assoc
int i; // текущий индекс
public:
assoc_iterator(assoc& s)
{
cs = &s; i = 0;
}
pair* operator()()
{
return (ifree)? &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";
}
Итераторный тип вроде этого имеет преимущество перед набором функций, которые выполняют ту же работу: у него есть собственные закрытые данные для хранения хода итерации. К тому же обычно существенно, чтобы одновременно могли работать много итераторов этого типа.
Конечно, такое применение объектов для представления итераторов никак особенно с перегрузкой операций не связано. Многие любят использовать итераторы с такими операциями, как first(), next() и last() (первый, следующий и последний).
Дата публикования: 2015-10-09; Прочитано: 191 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!