Язык программирования C++ для профессионалов


Ссылки - часть 2


void incr(int& aa) { aa++; }

void f() { int x = 1; incr(x); // x = 2 }

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

int next(int p) { return p+1; } void inc(int* p) { (*p)++; }

void g() { int x = 1; x = next(x); // x = 2 inc(&x); // x = 3 }

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

struct pair { char* name; // строка int val; // целое };

Идея заключается в том, что со строкой связывается некоторое целое значение. Нетрудно написать функцию поиска find(), которая работает со структурой данных, представляющей ассоциативный массив. В нем для каждой отличной от других строки содержится структура pair (пара: строка и значение ). В данном примере - это просто массив. Чтобы сократить пример, используется предельно простой, хотя и неэффективный алгоритм:

const int large = 1024; static pair vec[large+1];

pair* find(const char* p) /* // работает со множеством пар "pair": // ищет p, если находит, возвращает его "pair", // в противном случае возвращает неиспользованную "pair" */ { for (int i=0; vec[i].name; i++) if (strcmp(p,vec[i].name)==0) return &vec[i];

if (i == large) return &vec[large-1];

return &vec[i]; }

Эту функцию использует функция value(), которая реализует массив целых, индексируемый строками (хотя привычнее строки индексировать целыми):

int& value(const char* p) { pair* res = find(p); if (res->name == 0) { // до сих пор строка не встречалась, // значит надо инициализировать res->name = new char[strlen(p)+1]; strcpy(res->name,p); res->val = 0; // начальное значение равно 0 } return res->val; }




Начало  Назад  Вперед



Книжный магазин