Шаг 6.
Перегрузка функций

    На этом шаге мы рассмотрим перегрузку функций.

    Цель перегрузки функций состоит в том, чтобы функция с одним именем по-разному выполнялась и возвращала разные значения при обращении к ней с разными по типам и количеству фактическими параметрами. Например, может потребоваться функция, возвращающая максимальное из значений элементов одномерного массива, передаваемого ей в качестве параметра. Массивы, использованные как фактические параметры, могут содержать элементы разных типов, но пользователь функции не должен беспокоиться о типе результата. Функция всегда должна возвращать значение того же типа, что и тип массива - фактического параметра.

    Для обеспечения перегрузки функций необходимо для каждого имени определить, сколько разных функций связано с ним, т.е. сколько вариантов сигнатур допустимы при обращении к ним. Предположим, что функция выбора максимального значения элемента из массива должна работать для массивов типа int, long, float, double. В этом случае придется написать четыре разных варианта функции с одним и тем же именем. В следующей программе эта задача решена:

//RAZN6_1.СРР - перегрузка функций.
#include <iostream.h>
long max_element(int n, int array[]) 
// Функция для массивов с элементами типа int.
{ 
  int value = array[0];     
  for (int i = 1; i < n; i++)	
    value = value > array [i] ? value : array [i] ;
  cout << "\nДля (int)    : ";
  return long(value);
}

long max_element(int n, long array[]) 
// Функция для массивов с элементами типа long.
{ 
  long value = array[0];    
  for (int i = 1; i < n; i++)	
    value = value > array[i] ? value : array[i];
  cout << "\nДля (long)   : ";
  return value;
}

double max_element(int n, float array[]) 
// Функция для массивов с элементами типа float.
{ 
  float value = array[0];   
  for (int i = 1; i < n; i++)	
    value = value > array[i] ? value : array[i];
  cout << "\nДля (float)  : ";
  return double(value);
}

double max_element(int n, double array[]) 
// Функция для массивов с элементами типа double.
{ 
  double value = array[0];  
  for (int i = 1; i < n; i++)	
    value = value > array[i] ? value : array[i];
  cout << "\nДля (double) : ";
  return value;
}

void main()
{ 
  int x[] = { 10, 20, 30, 40, 50, 60 };
  long f[] = { 12L, 44L, 5L, 22L, 37L, 30L }; 
  float y[] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 }; 
  double z[] = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06 }; 
  cout << "max_elem(6,x) = " << max_element(6,x); 
  cout << "max_elem(6,f) = " << max_element(6,f); 
  cout << "max_elem(6,y) = " << max_element(6,y); 
  cout << "max elem(6,z) = " << max_element(6,z);
}
Текст этой программы можно взять здесь.

    Результат работы программы:

Для (int)      : max_elem (6,x) = 60
Для (long)     : max_elem (6,f) = 44
Для (float)    : max_elem (6,y) = 0.6
Для (double)   : max_elem (6,z) = 0.06

    В программе для иллюстрации независимости перегруженных функций от типа возвращаемого значения две функции, обрабатывающие целые массивы (int, long), возвращают значение одного типа long; функции, обрабатывающие вещественные массивы (double, float), обе возвращают значение типа double. Распознавание перегруженных функций при вызове выполняется по их сигнатурам. Перегруженные функции поэтому должны иметь одинаковые имена, но спецификации их параметров должны различаться по количеству и (или) по типам, и(или) по расположению.

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

    double multy (double x) { return x * х * х; }
    double multy (double x, double у) { return x * у * у; }
    double multy (double x, double у, double z)
                            { return x * у * z; }

    Каждое из следующих обращений к функции multy() будет однозначно идентифицировано и правильно обработано:

    multy (0.4) 
    multy (4.0, 12.3) 
    multy (0.1e-6, 1.2e4, 6.4)

    Однако добавление в программу такой функции прототипа с начальными значениями параметров:

    double multy (double a = 1.0, double b	= 1.0,
                          double с = 1.0, double d = 1.0);
    { return a * b + c * d; }					

навсегда запутает любой компилятор при попытках обработать, например, такой вызов:

    multy(0.1e-6, 1.2e4);




Предыдущий шаг Содержание