Как известно, в С можно присваивать адрес функции указателю и затем вызвать функцию с использованием этого указателя. Та же самая возможность имеется и в С++. Однако из-за наличия перегрузки функций этот процесс становится несколько более сложным. Для того, чтобы понимать причину сложностей, для начала рассмотрим инструкцию, присваивающую адрес функции myfunc() указателю р:
р = myfunc;
Если бы это было частью С-программы, то существовала бы одна и только одна функция с именем myfunc(), так что компилятор без труда присвоил бы ее адрес указателю р. Однако в программе на языке С++ функция myfunc() может быть перегружена. В таком случае каким образом компилятор может знать, какую именно функцию присваивать указателю р? Ответ зависит от того, каким образом объявлен указатель р. В качестве примера рассмотрим следующую программу:
#include <iostream.h>
int myfunc(int a);
int myfunc(int a, int b);
int main()
{
int (*fp) (int a); // указатель на int xxx(int)
fp = myfunc; // указывает на myfunc(int)
cout << fp(5);
return 0;
}
int myfunc (int a)
{
return a;
}
int myfunc (int a, int b)
{
return a*b;
}
Как показывает данная программа, fp объявлен как указатель на функцию, возвращающую целое число и имеющую один аргумент. С++ использует эту информацию, чтобы выбрать версию myfunc(int а) — версию функции myfunc(). Если бы fp было объявлено следующим образом:
int (*fp) (int a, int b);
то указателю fp был бы присвоен адрес функции myfunc(int a, int b) — версии функции myfunc().
Подведем итог. Когда адрес перегруженной функции присваивается указателю на функцию, то именно способ объявления этого указателя определяет, адрес какой из перегруженных функций будет присвоен этому указателю.