На этом шаге мы рассмотрим создание и использование ссылок на функции.
Подобно указателю на функцию определяется и ссылка на функцию:
тип_функции (& имя_ссылки) (спецификация_параметров) инициализирующее_ выражение;
Здесь тип функции - это тип возвращаемого функцией значения, спецификация_параметров определяет сигнатуру функций, допустимых для ссылки, инициализирующее_выражение - включает имя уже известной функции, имеющей тот же тип и ту же сигнатуру, что и определяемая ссылка. Например,
int ifunc (float, int) // Прототип функции. int (& iref) (float, int) = ifunc; // Определение ссылки.
iref - ссылка на функцию, возвращающую значение типа int и имеющую два параметра с типами float и int. Напомним, что использование имени функции без скобок (и без параметров) воспринимается как адрес функции.
Ссылка на функцию обладает всеми правами основного имени функции, т.е. является его синонимом (псевдонимом). Изменить значение ссылки на функцию невозможно, поэтому указатели на функции имеют гораздо большую сферу применения, чем ссылки.
Следующая программа иллюстрирует вызовы функции по основному имени, по указателю и по ссылке:
//RAZN4_1.СРР - ссылка и указатель на функцию. #include <iostream.h> void func(char c) // Определение функции. { cout << "\n" << c; } void main() { void (*pf)(char); // pf - указатель на функцию. void (&rf) (char) = func; // rf - ссылка на функцию. func('A'); // Вызов по имени. pf = func; // Указателю присваивается адрес функции. (*pf) ('В');// Вызов по адресу с помощью указателя. rf('C'); // Вызов по ссылке. }
Результат выполнения программы:
А В С
Определение ссылки может содержать ее инициализацию и в круглых скобках. В нашем примере была бы допустима и такая конструкция:
void (&rf)(char)(func); // rf - ссылка на функцию.
Так же можно инициализировать и указатель на функцию:
void (*pf)(char)(func); // pf - указатель на функцию.
На следующем шаге мы рассмотрим использование ссылок для возврата значений из функций.