Операторная функция operator[] задает для объектов классов интерпретацию индексации. Второй параметр этой функций (индекс) может иметь произвольный тип. Это позволяет, например, определять ассоциативные массивы. В качестве примера можно переписать определение из §2.3.10, где ассоциативный массив использовался в небольшой программе, подсчитывающей число вхождений слов в файле.
Там для этого использовалась функция. Мы определим настоящий тип ассоциативного массива:
class assoc { struct pair { char* name; int val; };
pair* vec; int max; int free;
assoc(const assoc&); // предотвращает копирование assoc& operator=(const assoc&); // предотвращает копирование public: assoc(int); int& operator[](const char*); void print_all(); };
В объекте assoc хранится вектор из структур pair размером max.
В переменной free хранится индекс первого свободного элемента вектора.
Чтобы предотвратить копирование объектов assoc, конструктор копирования и операция присваивания описаны как частные. Конструктор выглядит так:
assoc::assoc(int s) { max = (s<16) ? 16 : s; free = 0; vec = new pair[max]; }
В реализации используется все тот же неэффективный алгоритм поиска, что и в §2.3.10. Но теперь, если вектор переполняется, объект assoc увеличивается:
#include <string.h>
int& assoc::operator[](const char* p) /* работает с множеством пар (структур pair): проводит поиск p, возвращает ссылку на целое значение из найденной пары, создает новую пару, если 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; i<max; i++) nvec[i] = vec[i]; delete vec; vec = nvec; max = 2*max; }
pp = &vec[free++]; pp->name = new char[strlen(p)+1]; strcpy(pp->name,p); pp->val = 0; // начальное значение = 0 return pp->val; }
Поскольку представление объекта assoc скрыто от пользователя, нужно иметь возможность напечатать его каким-то образом. В следующем разделе будет показано как определить настоящий итератор для такого объекта.
Здесь же мы ограничимся простой функцией печати: