Программирование на C и C++

Онлайн справочник программиста на C и C++

Определение адреса перегруженной функции

Как известно, в С можно присваивать адрес функции указателю и затем вызвать функцию с ис­пользованием этого указателя. Та же самая возможность имеется и в С++. Однако из-за наличия перегрузки функций этот процесс становится несколько более сложным. Для того, чтобы пони­мать причину сложностей, для начала рассмотрим инструкцию, присваивающую адрес функции 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().

Подведем итог. Когда адрес перегруженной функции присваивается указателю на функцию, то именно способ объявления этого указателя определяет, адрес какой из перегруженных функций будет присвоен этому указателю.