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

Последнее обновление: 06.03.2023

Язык С++ позволяет определять функции с одним и тем же именем, но разным набором параметров. Подобная возможность называется перегрузкой функций (function overloading). Компилятор же на этапе компиляции на основании параметров выберет нужный тип функции.

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

  • имеют разное количество параметров

  • соответствующие параметры имеют разный тип

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

Рассмотрим простейший пример:

#include <iostream>

int sum(int, int);
double sum(double, double);

int main()
{
    int result1 {sum(3, 6)}; // выбирается версия int sum(int, int)
    std::cout << result1 << std::endl; // 9

    
    double result2 {sum(3.3, 6.6)}; // выбирается версия double sum(double, double)
    std::cout << result2 << std::endl; // 9.9
}
int sum(int a, int b)
{
    return a + b;
}
double sum(double a, double b)
{
    return a + b;
}

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

int result1 {sum(3, 6)};

Соответственно для этого вызова выбирается версия

int sum(int, int);

Во втором вызове в функцию передаются числа с плавающей точкой:

double result2 {sum(3.3, 6.6)};

Поэтому выбирается версия, которая принимает числа double:

double sum(double, double);

Аналогично перегруженные версии функции могут отличаться по количеству параметров:

#include <iostream>

int sum(int, int);
int sum(int, int, int);

int main()
{
    int result1 {sum(3, 6)}; // выбирается версия int sum(int, int)
    std::cout << result1 << std::endl; // 9

    
    int result2 {sum(3, 6, 2) }; // выбирается версия int sum(int, int, int)
    std::cout << result2 << std::endl; // 11
}
int sum(int a, int b)
{
    return a + b;
}
int sum(int a, int b, int c)
{
    return a + b + c;
}

Перегрузка функций и параметрами-ссылки

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

void print(int);
void print(int&);

Не считаются разными версиями функции print.

Перегрузка и параметры-константы

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

void print(int);
void print(const int);

Во втором прототипе компилятор игнорирует оператор const.

Пример перегрузки функции с константными параметрами

#include <iostream>

int square(const int*);
int square(int*);

int main()
{
    const int n1{2};
    int n2{3};
    int square_n1 {square(&n1)};
    int square_n2 {square(&n2)};
    std::cout << "square(n1): " << square_n1 << "\tn1: " << n1 << std::endl;
    std::cout << "square(n2): " << square_n2 << "\tn2: " << n2 << std::endl;
}

int square(const int* num)
{
    return *num * *num ;
}
int square(int* num)
{
    *num = *num * *num; // изменяем значение по адресу в указателе
    return *num;
}

Здесь функция square принимает указатель на число и возводит его в квадрат. Но первом случае параметр представляет указатель на константу, а во втором - обычный указатель.

В первом вызове

int square_n1 {square(&n1)};

Компилятор будет использовать версию

int square(const int*);

так как передаваемое число n1 представляет константу. Поэтому переданное в эту функцию число n1 не изменится.

В втором вызове

int square_n2 {square(&n2)};

Компилятор будет использовать версию

int square(int*);

в которой для примера также меняется передаваемое значение. Поэтому переданное в эту функцию число n2 изменит свое значение. Консольный вывод программы

square(n1): 4   n1: 2
square(n2): 9   n2: 9

С передачей константной ссылки все будет аналогичо.

Дополнительные материалы
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850