Чтобы задать смысл индексов для объектов класса используется функция operator[]. Второй параметр (индекс) функции operator[] может быть любого типа. Это позволяет определять ассоциативные массивы и т.п. В качестве примера давайте перепишем пример из этого пункта, где при написании небольшой программы для подсчета числа вхождений слов в файле применялся ассоциативный массив. Там использовалась функция. Здесь определяется надлежащий тип ассоциативного массива:
struct pair { char* name; int val; };
class assoc { pair* vec; int max; int free; public: assoc(int); int& operator[](char*); void print_all(); };
В assoc хранится вектор пар pair длины max. Индекс первого неиспользованного элемента вектора находится в free. Конструктор выглядит так:
assoc::assoc(int s) { max = (s<16) ? s : 16; free = 0; vec = new pair[max]; }
При реализации применяется все тот же простой и неэффективный метод поиска, что использовался в этом пункте. Однако при переполнении assoc увеличивается:
#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]; 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(); }
8 8 8
|