|
|||
Значения параметров по умолчанию.Значения параметров по умолчанию. Что бы упростить вызов функции, в ее заголовке можно указать значения параметров по умолчанию. Эти параметры должны быть последними в списке и могут опускаться при вызове функции. Если при вызове параметр опущен, должны быть опущены и все параметры, идущие за ним. В качестве значений параметров по умолчанию могут использоваться константы, глобальные переменные и выражения. int f(int a, int b = 0); void f1(int, int = 100, char* = 0); /*обратите внимание на пробел между * и = без него получилась бы операция сложного присваивания */ void err(int errValue = errno) //errno- глобальная переменная ....... f(100); f(a, 1); //так можно f1(a); f1(a, 10); f1(a, 10, ‘Vasia’); //и так тоже можно f1(a, ,’Vasia’); //а так нельзя! Перегрузка функций. Часто бывает удобно, что бы функции, реализующий один и тот же алгоритм для различных типов данных, имели одно и то же имя. Если это имя мнемонично, то есть несет нужную информацию, это делает программу более понятной, поскольку для каждого действия требуется помнить только одно имя. Использование нескольких функций с одним и тем же именем, но с различными типами параметров, называется перегрузкой функций. Компилятор определяет, какую именно функцию требуется вызвать, по типу фактических параметров. Этот процесс называется разрешением перегрузки, от resolution в смысле «уточнение». Тип возвращаемого функцией значения в разрешении не участвует. Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводиться к тому, что бы использовать функцию с наиболее подходящими аргументами и выдать сообщение, если такая не найдется. Допустим, имеется 4 варианта функции, определяющей наибольшее значение: int max(int, int); char* max(char*, char*);//максимум из длин строк int max(int, char*);//максимум из целого и длины строки int max(char*, int); void f(int a, int b, char* c, char* d){ cout << max(a, b) << max(c, d) << max(a, c) << max(c, b); } Здесь последовательно вызовутся все 4 варианта функции. Если точного соответствия не найдено, выполняются передвижения порядковых типов в соответствии с общими правилами: bool и char в int, float в double и т.д. Далее выполняются стандартные преобразования типов, int в double, или указателей в void*. следующим шагом являются преобразования типов, заданных пользователем, а так же поиск соответствия за счет переменного числа аргументов функции. Если соответствие на одном и том же этапе может быть получено более чем одним способом, вызов считается неоднозначным и выдается сообщение об ошибке. Неоднозначность может появиться при: · преобразовании типа · использовании параметров- ссылок · использовании аргументов по умолчанию Пример неоднозначности преобразования типов: #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.09; double y = 10.09; cout << f(x) << endl; cout << f(y) << endl; /*cout << f(10) << endl;*/ return 0; } Для устранения данной неоднозначности требуется явное преобразование типа для константы 10: cout << f(double (10)) << endl; Пример неоднозначности при использовании параметров-ссылок: если одна из перегружаемых функций объявлена как int f(int a, int b), а другая как intf(int a, int& b), т.к. нет синтаксических различий между вызовом функции, которая получает параметр по значению, и вызовом функции, которая получает параметр по ссылке. Пример неоднозначности при использовании аргументов по умолчанию: #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); /* cout << f(10) не понятно какая из функций вызывается*/ return 0; } Правила описания перегружаемых функций: · Перегруженные функции должны находиться в одной области видимости, иначе произойдет сокрытие, аналогично одинаковым именам переменных во вложенных блоках. · Перегруженные функции могут иметь параметры по умолчанию, при этом значения одного и того же параметра в разных функциях должны совпадать. В различных вариантах перегруженных функций может быть различное количество параметров по умолчанию. · Функции не могут быть перегружены, если их описание параметров отличаются только модификаторами const или использованием ссылки (например, int и const int, int и &int).
|
|||
|