HTML [44] |
Visual C++ и MFC [21] |
c++ [78] |
php [19] |
Javascript [15] |
C# [51] |
загрузки [0] |
XNA
[10]
создание игр с помощью xna
|
Главная » Статьи » c++ |
Перегрузка функцийПродолжаем исследовать волшебный мир С++! Как показывает опыт, большинство людей, которые изучают язык программирования, или совсем не обращают, или не уделяют особого внимания вопросу связанному с именами функций. Подумайте, как назвать переменную или функцию? Если у Вас появился ответ: "Главное чтобы функция работала, а как она будет называться неважно..." - то он имеет право на существование, но в большинстве ситуаций - неправильный. Объясним почему. Вы уже освоили азы С++, разработали большое количество программ. При создании программ у Вас вырабатывается собственный стиль написания (почти как почерк). Если проект разрабатывается группой программистов (а это все "серьезные" программы, такие как Corel, Photoshop и т.д.), то немаловажно, чтобы Ваш стиль написания был понятен другим программистам. Обычно, выбор имени функции основан на стремлении отразить в названии ее основное назначение. "Читабельные" программы, как правило, содержат разнообразные и грамотно подобранные идентификаторы. Иногда, различные функции используются для одних и тех же целей. Согласитесь, что логично дать этим функциям одинаковые имена, которые бы отображали суть выполняемых действий этими функциями. Как программист, Вы можете сделать это используя механизм перегрузки функций. Перегрузка (от англ. overloading) использует одно и то же имя для нескольких вариантов функции. Другими словами, несколько функций могут иметь одинаковые имена. Но тогда появляется вопрос: «А как компилятор сможет различить две одинаковые функции?» Т.е. если имена функций одинаковы, то как компилятор узнает, какую функцию необходимо вызвать в данный момент?. Выбор конкретного варианта зависит от типов аргументов, используемых функцией. Другими словами, компилятор различает функции с одинаковыми именами по параметрам, которые передаются в эту функцию. Программисты говорят, что компилятор отличает одну функцию от другой по ее сигнатуре. Под сигнатурой понимается список типов, который используется в объявлении функции. Сигнатура функции задается числом, порядком следования и типами параметров. Имена функций могут быть перегружены в пределах одной и той же области видимости. Перегруженные функции являются важным дополнением С++. Конкретная функция выбирается в зависимости от соответствия списка аргументов при вызове функции списку параметров в объявлении функции. Когда вызывается перегруженная функция, компилятор должен иметь алгоритм для выбора надлежащей функции. Алгоритм, который выполняет этот выбор, зависит от того, преобразования какого типа присутствуют. Наилучшее соответствие должно быть уникальным. Оно должно быть лучшим по крайней мере для одного аргумента и так же хорошо, как остальные соответствия, для всех аргументов. Отметим, что в ранних версиях С++ в начале области видимости, в которых выполнялась перегрузка, требовалось ключевое слово overload. Но, спешим Вас обрадовать, в Visual C++ это слово не применяется и, более того, исключено из списка ключевых слов. Рассмотрим пример перегруженных функций. Учебный пример перегруженных функций. Иллюстрация перегрузки#include <iostream.h> #include <string.h> int noName(int first) //Первая функция { return first*first; } int noName(unsigned int first) //Вторая функция c тем же именем { return -first*first; } char noName(char first) //Третья функция c тем же именем { return first+3; } int noName(int first, char *second) //Четвертая функция c тем же именем { return first*strlen(second); } int noName(int first, char second) //Пятая функция c тем же именем { return first*second; } float noName(float r) //Шестая функция c тем же именем { return r*r; } double noName(double r) //Седьмая функция c тем же именем { return r*r; } void main() { cout<<noName(4)<<endl; //Вызов первой функции cout<<noName((unsigned)4)<<endl;//Вызов второй функции cout<<noName('a')<<endl; //Вызов третьей функции cout<<noName(4,"abc")<<endl; //Вызов четвертой функции cout<<noName(4,'a')<<endl; //Вызов пятой функции cout<<noName((float)1.2)<<endl; //Вызов шестой функции cout<<noName((double)1.2)<<endl;//Вызов седьмой функции } Результат работы программы16 -16 d 12 388 1.44 1.44 В приведенной выше программе функция noName перегружена семь раз. Первые два определения отличаются только одним параметром int first и unsigned int first. Четвертое и пятое опеределения отличаются типом второго параметра (соответственно char и char*). Шестое и седьмое определения отличаются тем, что у одного параметр имеет тип float, а у другого — double. Подозреваем, что у Вас уже появилось несколько вопросов, связанных с описанной выше теорией и практикой. Ниже приведены ответы на несколько распространенных вопросов по перегрузке функций.
Еще раз напомним, что компилятор выбирает функцию в соответствии с типами аргументов и их количеством. Правило, по которому осуществляется этот выбор, называется алгоритмом соответствия сигнатуре (в оригинале это пишется как signature matching algorithm). | |
Просмотров: 4545 | Комментарии: 2 | Рейтинг: 0.0/0 |
Всего комментариев: 2 | |
| |