
Вказівники на функції
В C++ вказівники можуть посилатися на функції. Ім'я функції саме по собі представляє константний вказівник на цю функцію, тобто містить адреса входу в неї. Однак можна задати свій власний вказівник на дану функцію:
тип ( *ім'я_вказівника ) ( cпиcoк_типів_аргументів )
Наприклад,
bool ( *Funcptr ) ( char, long ) ;
оголошує вказівник Funcptr, що посилається на функцію, яка повертає логічне значення, та приймає в якості параметрів одну символьну й одну цілую довгу змінну.
Виклик функції через вказівник здійснюється так, начебто ім'я вказівника є просто іменем викликуваної функції. Тобто після імені вказівника вказується список аргументів, очікуваних функцією. Так, для наведеного вище вказівника на функцію Funcptr виклик може виглядати, наприклад, у такий спосіб:
bool flag ;
char Symbol = 'x' ;
long Num = 202L ;
flag = Funcptr ( Symbol, Num ) ;
Розглянемо приклад використання вказівника на функцію. Нехай задане яке-небудь ціле число, що характеризує місяць у році. Потрібно визначити, до якого сезону року ставиться даний місяць.
#include <iostream.h>
bool Isspring ( int ) ;
bool Issummer ( int ) ;
bool Isautumn ( int ) ;
bool Iswinter ( int ) ;
void main ()
{
int Month = 4 ;
bool ( *pfunc ) ( int ) = Iswinter ; if ( pfunc ( Month ) ) cout << "Зима" ;
ppunc = Isautumn ; if ( pfunc ( Month ) ) cout << "Осінь" ;
pfunc = Issummer ; if ( pfunc ( Month ) ) cout << "Літо" ;
pfunc = Isspring; if ( pfunc ( Month ) ) cout << "Весна" ;
}
bool Isspring (int x) { return ( x > 2 && x < 6 ) ; }
bool Issummer (int x) { return ( x > 5 && x < 9 ) ; }
bool Isautumn (int x) { return ( x > 8 && x<12 ) ; }
bool Iswinter (int x) { return ( x>11 || x < 3 ) ; }
У наведеній програмі створюється вказівник pfunc на функцію, що приймає один цілий аргумент й повертає логічне значення, ініціалізований адресою функції Iswinter. Далі через вказівник по черзі викликаються функції, що визначають, чи попадає прийнятий аргумент у заданий діапазон. Логічні значення, що вертаються функціями, визначають, виводити чи ні на екран повідомлення.
Вказівники на функції використовуються часто в якості аргументів інших функцій. У такий спосіб створюються універсальні функції, що значно спрощують текст складної програми (наприклад, чисельне рішення рівнянь, диференціювання, інтегрування). Деякі бібліотечні функції як параметр також приймають покажчики на функції.
Посилання
Посилання - особливий тип даних, що є схованої формою вказівника, який при використанні автоматично розіменовується. Іншими словами, він може використовуватися просто як інше ім'я, або псевдонім об'єкта. При оголошенні посилання перед її іменем ставиться знак амперсанта, а сама вона повинна бути відразу проініціалізована іменем того об'єкта, на який посилається:
тип &ім'я_посилання = ім'я_змінної ;
Тип об'єкта, на який вказується посилання, може бути будь яким. Оголошення неініціалізованного посилання викличе повідомлення компілятора про помилку ( крім ситуації, коли посилання оголошується як extern). Будь-яка зміна значення посилання спричинить зміну того об'єкта, на який дане посилання вказує:
int V = 0 ; // оголошення змінної типу int
int &ref = V ; // оголошення посилання на змінну типу int і її ініціалізація
ref += 10 ; // те ж, що й V += 10
Після виконання наведеного фрагмента значення обох змінні V і ref буде рівно 10. Використання посилань не пов'язане з додатковими витратами пам'яті.
Посилання не можна перепризначувати. Спроба перепризначити наявне посилання який-небудь інший змінної приведе до присвоєння оригіналу об'єкта значення іншої змінної:
char A = 'А', B = 'В' ; // оголошення змінних A і B типу char їх ініціалізація
char &refА = A ; // оголошення посилання на змінну A і її ініціалізація
refa = В ; // присвоєння посилання refa значення змінної B
cout << refa; // виводить на екран символ ‘B’’
Крім того, слід урахувати, що посилатися можна тільки на сам об'єкт. Не можна оголосити посилання на тип об'єкта. Ще одне обмеження, що накладає на посилання, полягає в тому, що вони не можуть указувати на нульовий об'єкт яку має значення null). Таким чином, якщо є ймовірність того, що об'єкт у результаті роботи додатка стане нульовим, від посилання слід відмовитися на користь застосування вказівника.