Выбрать главу

В этом разделе мы узнаем об одной из самых удивительных возможностей языка C++ — перегрузке функций. В C++ несколько функций могут иметь одинаковые имена, но при условии, что их параметры будут различными. Такую ситуацию называют перегрузкой функций (function overloading), а функции, которые в ней задействованы, — перегруженными (overloaded). Перегрузка функций — один из способов реализации полиморфизма в C++.

Рассмотрим простой пример перегрузки функций.

// "Трехкратная" перегрузка функции f().

#include <iostream>

using namespace std;

void f(int i); // один целочисленный параметр

void f(int i, int j); // два целочисленных параметра

void f(double k); // один параметр типа double

int main()

{

 f (10); // вызов функции f(int)

 f(10, 20); // вызов функции f (int, int)

 f(12.23); // вызов функции f(double)

 return 0;

}

void f(int i)

{

 cout << "В функции f(int), i равно " << i << '\n';

}

void f(int i, int j)

{

 cout << "В функции f(int, int), i равно " << i;

 cout << ", j равно " << j << '\n';

}

void f(double k)

{

 cout << "В функции f(double), k равно " << k << ' \n';

}

При выполнении эта программа генерирует следующие результаты.

В функции f(int), i равно 10

В функции f(int, int), i равно 10, j равно 20

В функции f(double), к равно 12.23

Как видите, функция f() перегружается три раза. Первая версия принимает один целочисленный параметр, вторая — два целочисленных параметра, а третья — один double-параметр. Поскольку списки параметров для всех трех версий различны, компилятор обладает достаточной информацией, чтобы вызвать правильную версию каждой функции. В общем случае для создания перегрузки некоторой функции достаточно объявить различные ее версии.

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

Чтобы лучше понять выигрыш от перегрузки функций, рассмотрим три функции из стандартной библиотеки: abs(), labs() и fabs(). Они были впервые определены в языке С, а затем ради совместимости включены в C++. Функция abs() возвращает абсолютное значение (модуль) целого числа, функция labs() возвращает модуль длинного целочисленного значения (типа long), a fabs() — модуль значения с плавающей точкой (типа double). Поскольку язык С не поддерживает перегрузку функций, каждая функция должна иметь собственное имя, несмотря на то, что все три функции выполняют, по сути, одно и то же действие. Это делает ситуацию сложнее, чем она есть на самом деле. Другими словами, при одних и тех же действиях программисту необходимо помнить имена всех трех (в данном случае) функций вместо одного. Но в C++, как показано в следующем примере, можно использовать только одно имя для всех трех функций.

// Создание функций myabs() — перегруженной версии функции abs().

#include <iostream>

using namespace std;

// Функция myabs() перегружается тремя способами.

int myabs(int i);

double myabs(double d);

long myabs(long l);

int main()

{

 cout << myabs(-10) << "\n";

 cout << myabs(-11.0) << "\n";

 cout << myabs(-9L) << "\n";

 return 0;

}