Перегрузка и шаблоны функций в С++

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

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

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

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

Шаблоны функций

Многие алгоритмы не зависят от типов данных, с которыми они работают (классический пример — сортировка).

Естественно желание параметризовать алгоритм таким образом, чтобы его можно было использовать для различных типов данных.

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

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

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

В C++ есть мощное средство параметризации — шаблоны.

Существуют шаблоны функций и шаблоны классов.

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

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

Формат простейшей функции-шаблона:
template  заголовок{ 
/* тело функции */ 
} 
Вместо слова Туре может использоваться произвольное имя.
template void f(){ ... } Например, функция, сортирующая методом выбора массив из n элементов любого типа, в виде шаблона может выглядеть так:
template  
void sort__vybor(Type *b, int n){ 
Type a; //буферная переменная для обмена элементов 
for (int i = 0; i < n-l; 1++){ 
int imin = i; 
for (int j= i+1; j < n; j++) 
if (b[j] < b[imin]) imin = j ; 
а = b[i]; b[i] = b[imin]; b[imin] = а; 
} 
}
Главная функция программы, вызывающей эту функцию-шаблон, может иметь вид:
#include  
template  void sort_vybor(Type *b. int n);
int main(){ 
const int n = 20; 
int i, b[n]; 
for (i = 0; i> b[i]; 
sort_vybor(b. n); // cортировка целочисленного массива 
for (i = 0; i < n: i++) cout << b [ i ] << ' '; 
cout << endl; 
double a[] = {0.22, 117, -0.08, 0.21, 42.5}; 
sort_vybor(a, 5); // cортировка массива вещественных чисел 
for (i = 0; i < 5; i++) cout << а[i] << ' '; 
return 0; 
}
Первый вызов функции, который использует конкретный тип данных, приводит к созданию компилятором кода для соответствующей версии функции. Этот процесс называется инстанцированием шаблона (instantiation).

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

STUDLAB Сообщить про опечатку на сайте