Инструменты пользователя

Инструменты сайта


examination:ccc:question8

Вопрос №8. Перегрузка функций.

Перегрузка процедур и функций - возможность использования одноимённых подпрограмм: процедур или функций в языках программирования.

Зачем это нужно?

При определении функций в своих программах вы должны указать тип возвращаемого функцией значения, а также количество параметров и тип каждого из них. Например, если у вас есть функция с именем add_values, которая работает с двумя целыми значениями, а вы хотите использовать подобную функцию для сложения трех целых значений, вам следовало бы создать функцию с другим именем. Например, вы могли бы использовать add_two_values и add_three_values. Аналогично если вы хотели использовать подобную функцию для сложения значений типа float, то вам была бы необходима еще одна функция с еще одним именем. Чтобы избежать дублирования функции, C++ позволяет вам определять несколько функций с одним и тем же именем, но с разным количеством и типом аргументов. В процессе компиляции C++ принимает во внимание количество аргументов, используемых каждой функцией, и затем вызывает именно требуемую функцию. Предоставление компилятору выбора среди нескольких функций называется перегрузкой. При использовании перегрузки функций необходимо внимательно относиться к спискам аргументов, так как именно они являются ключевым фактором, определяющим, какой из вариантов функции будет выбран.

На заметку

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

Не считается перегрузкой, а считается переопределением:

  • Если типы аргументов функций совпадают или являются синонимами
  • Если в одной функции используются те же аргументы, что и в другой, но для одного или нескольких из этих аргументов заданы значения по умолчанию
  • Если объявление аргументов одной функции отличается от объявления аргументов другой лишь некоторыми модификаторами

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

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

Мысли компилятора

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

При анализе функции компилятор определяет функции-кандидаты на проверку соответствия. Функция-кандидат должна иметь то же имя, что и анализируемая функция, и ее объявление должно быть видимым в точке вызова анализируемой функции. При этом возможно три случая:

  1. Компилятор находит единственную функцию, которая является полным соответствием для фактических параметров, и генерирует код, чтобы вызвать эту функцию.
  2. Компилятор не находит ни одной функции, совпадающей по параметрам с данной. В таком случае компилятор выдает ошибку.
  3. Компилятор находит несколько функций, которые соответствуют заданным параметрам. Но ни одна из них не является явно лучшей. В этом случае компилятор выдает ошибку о неоднозначности запроса.

Если нашлись подходящие функции-кандидаты, компилятор определяет жизнеспособные функции. Для того чтобы функция была жизнеспособной необходимо выполнение 2 условий:

  1. У функции-кандидата должно быть то же количество аргументов, что и у анализируемой
  2. Тип каждого параметра функции-кандидата должен соответствовать типу параметра анализируемой функции, либо быть конвертируемым.

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

  • Соответствие для каждого параметра не хуже, чем соответствие, требуемое любой другой жизнеспособной функцией
  • Есть не менее одного параметра, для которого соответствие лучше, чем соответствие, обеспеченное любой другой жизнеспособной функцией.

Если после рассмотрения всех параметров не найдется полностью соответствующей функции, то компилятор выдаст ошибку неоднозначности запроса.

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

Единственная функция, которую нельзя перегружать, это функция main.

Пример

#include <iostream.h>
 
int add_values(int a,int b){
   return(a + b);
)
 
int add_values (int a, int b, int c){
   return(a + b + c);
}
 
void main(void){
   cout << "200 + 801 = " << add_values(200, 801) << endl;
   cout << "100 + 201 + 700 = " << add_values(100, 201, 700) << endl;
}

Как видите, программа определяет две функции с именами add_values Первая функция складывает два значения типа int, в то время как вторая складывает три значения. Вы не обязаны что-либо предпринимать специально для того, чтобы предупредить компилятор о перегрузке, просто используйте ее. Компилятор разгадает, какую функцию следует использовать, основываясь на предлагаемых программой параметрах.

examination/ccc/question8.txt · Последние изменения: 2014/01/15 12:13 (внешнее изменение)