Среда, 08.01.2025, 20:20
Главная Регистрация RSS поиск
Приветствую Вас, Гость
Меню сайта
Категории раздела
HTML [44]
Visual C++ и MFC [21]
c++ [78]
php [19]
Javascript [15]
C# [51]
загрузки [0]
XNA [10]
создание игр с помощью xna
Наш опрос
Каким языком программирования вы увлекаетесь
Всего ответов: 2420
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Реклама
Главная » Статьи » 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.

Подозреваем, что у Вас уже появилось несколько вопросов, связанных с описанной выше теорией и практикой. Ниже приведены ответы на несколько распространенных вопросов по перегрузке функций.

ВОПРОС: Что, если из предпоследней строки описанной программы убрать операцию приведения типов (float)?
ОТВЕТ: Компилятор будет счетать, что константа 1.2 имеет тип double. Соотвественно, будет вызвана функция которая имеет следующий заголовок:
double noName(double r)        //Седьмая функция c тем же именем
ВОПРОС: Что, если в описанную программу добавить следующее опеределение функции?
float noName(int first)

                        {

                                return (float) first*first;

                        }
                    
ОТВЕТ: Компилятор выдаст сообщение об ошибке, поскольку сигнатуры уже определенной и новой функций не имеют отличий. Сигнатура функции не зависит от типа возвращаемого ею значения. Другими словами, компилятор не сможет перегрузить функции, если они отличаются только типом возвращаемых значений.

Еще раз напомним, что компилятор выбирает функцию в соответствии с типами аргументов и их количеством. Правило, по которому осуществляется этот выбор, называется алгоритмом соответствия сигнатуре (в оригинале это пишется как signature matching algorithm).

Категория: c++ | Добавил: slava (29.04.2011)
Просмотров: 4545 | Комментарии: 2 | Рейтинг: 0.0/0
Всего комментариев: 2
2 slava  
0
что то не понятно?

1 IcyHot  
0
Че так мало-то!)))

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]