Pointer la funcție ca valoare returnată
O funcție poate returna un pointer către altă funcție. Acest lucru este util în cazul în care avem un număr limitat de opțiuni — funcții care pot fi executate — și trebuie să alegem una dintre ele. Alegerea și setul de opțiuni sunt determinate de o funcție intermediară.
Să analizăm un exemplu simplu:
#include <iostream>
void goodmorning();
void goodevening();
void(*message(unsigned))();
int main()
{
void(*action)(){message(10)}; // pointer către funcția selectată
action(); // Good Morning!
action = message(16); // obținem altă funcție
action(); // Good Evening!
}
void(*message(unsigned hour))()
{
if (hour > 15)
return goodevening;
else
return goodmorning;
}
void goodmorning()
{
std::cout << "Good Morning!" << std::endl;
}
void goodevening()
{
std::cout << "Good Evening!" << std::endl;
}
Aici este definită funcția message, care în funcție de ora transmisă ca parametru, returnează una dintre funcțiile goodmorning sau goodevening. Să analizăm semnătura funcției:
void(*message(unsigned hour))()
Mai întâi este indicat tipul funcției returnate — void, deoarece funcțiile goodmorning și goodevening nu returnează nimic. În paranteze este declarat numele funcției message și parametrul ei — unsigned. După aceea, se specifică parametrii funcției returnate — în acest caz, () fiindcă nu are parametri.
Numele funcției este de fapt un pointer la ea, deci în message putem face:
return goodmorning;
Pentru a stoca pointerul, se definește o variabilă:
void(*action)();
Aceasta este un pointer către o funcție fără parametri și cu tip de retur void.
Exemplu de apel:
action = message(16); // returnează goodevening
action(); // apelează funcția
Exemplu mai complex: în funcție de alegerea utilizatorului, este returnată o operație aritmetică:
#include <iostream>
int add(int, int);
int subtract(int, int);
int multiply(int, int);
int(*select(int))(int, int);
int main()
{
int(*action)(int, int) {select(1)};
std::cout << action(8, 5) << std::endl; // 13
action = select(2);
std::cout << action(8, 5) << std::endl; // 3
action = select(3);
std::cout << action(8, 5) << std::endl; // 40
}
int(*select(int choice))(int, int)
{
switch (choice)
{
case 2:
return subtract;
case 3:
return multiply;
default:
return add;
}
}
int add(int x, int y) { return x + y; }
int subtract(int x, int y) { return x - y; }
int multiply(int x, int y) { return x * y; }
Aici, funcția select() primește o alegere (1, 2 sau 3) și returnează funcția corespunzătoare. Tipul funcției este:
if (choice >0 && choice<4)
return actions[choice - 1];
else
return nullptr;
adică o funcție care returnează un pointer la funcție ce primește doi int și returnează un int.
Putem adăuga o verificare suplimentară, dacă alegerea nu corespunde unei funcții:
#include <iostream>
int add(int, int);
int subtract(int, int);
int multiply(int, int);
int(*select(int))(int, int);
int main()
{
int(*action)(int, int) {select(14)};
if(action)
{
std::cout << action(8, 5) << std::endl;
}
else
{
std::cout << "Undefined" << std::endl;
}
}
int(*select(int choice))(int, int)
{
int (*actions[])(int, int){ add, subtract, multiply };
if (choice > 0 && choice < 4)
return actions[choice - 1];
else
return nullptr;
}
int add(int x, int y) { return x + y; }
int subtract(int x, int y) { return x - y; }
int multiply(int x, int y) { return x * y; }