long b; b=8;
cout << rotate(a) << “\n”;
cout << rotate(b) << “\n”;
return 0;
}
//-------------------------------------------------------------int rotate(int i)
{
int x;
if ( i & 0x8000) x=1;
else x=0;
i = i<<1;
i += x;
return i;
}
//-------------------------------------------------------------long rotate(long i)
{
int x;
if ( i & 0x80000000) x=1;
else x=0;
i = i<<1;
i += x;
return i;}
Процесс определения компилятором вызываемой функции (по набору фактических параметров) называется разрешением перегрузки. Механизм разрешения перегрузки основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать функцию с наиболее подходящими аргументами и выдать сообщение, если такой не найдется.
Если точного соответствия не найдено, выполняется:
· продвижение порядковых типов в соответствии с общими правилами (bool и char в int, float в double и т.д.);
· стандартные преобразования типов (int в double, указатели в void*);
· преобразование типов, заданное пользователем;
· поиск соответствий за счет переменного числа аргументов функций.
Если соответствие на одном и том же этапе может быть получено более чем одним способом, вызов считается неоднозначным и выдается сообщение об ошибке.
Неоднозначность может появиться:
· при преобразовании типа;
· при использовании параметров-ссылок и модификатора const;
· при использовании аргументов по умолчанию;
· если описание функций отличается только типом возвращаемого значения (например, int FUN2(int); и float FUN2(int);).
Пример неоднозначности при преобразовании типа:
#include <iostream.h>
float f(float i) {
cout << “function float f(float i)” << endl;
return i;
}
double f(double i){
cout << “function double f(double i)” << endl;
return i*2;
}
int main()
{float x=10.09f;
double y=10.09;
cout << f(x) <<endl ; //вызывается f(float), неоднозначности нет
cout << f(y) <<endl ; //вызывается f(double), неоднозначности нет
//cout <<f(10) <<endl ; //ошибка компиляции, т.к. имеется неоднозначность: //как преобразовать 10: в тип float или в тип double */
return 0;
}
Для устранения этой неоднозначности требуется выполнить явное приведение типа для константы 10 (например, static_cast <float> (10) ).
Пример неоднозначности при использовании параметров-ссылок и модификатора const
Пусть одна из перегружаемых функций объявлена как
int f(int a, int b); а другая – как int f(int a, int &b);
и есть вызов функции f(a, b);
Компилятор не может узнать, какая из этих функций вызывается, так как нет синтаксических различий между вызовом функции, которая получает параметр по значению, и вызовом функции, которая получает параметр по ссылке.
Аналогичная ситуация возникает и если описание параметров отличается только модификатором const.
Пример неоднозначности при использовании аргументов по умолчанию
#include <iostream.h>
int f(int a){return a;}
int f(int a, int b=1){ return a*b;}
int main()
{
cout << f (10, 2) << endl; //вызывается f(int, int);
//cout << f (10) << endl; //ошибка компиляции, т.к. имеется неоднозначность // – что вызывается f(int, int) или f(int) ?
return 0;
}
Правила описания перегруженных функций:
· Компилятор автоматически выбирает необходимую версию функции на основании типа аргументов в вызове функции.
· Разрешается перегружать функции, отличающиеся количеством параметров. Тогда конкретный вариант функции компилятор выберет на основании количества аргументов в вызове функции.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.