Семинар 1. Шаблоны функций и классов
Цель введения шаблонов функций - автоматизация создания функций, которые могут обрабатывать разнотипные данные. В отличие от механизма перегрузки, когда для каждого набора формальных параметров определяется своя функция, шаблон семейства функций определяется один раз, но это определение параметризуется. Параметризовать в шаблоне функций можно тип возвращаемого функцией значения и типы любых параметров, количество и порядок размещения которых должны быть фиксированы. Для параметризации используется список параметров шаблона.
Задание по написанию шаблонных функций и классов:
Описание шаблонной функции для обмена значений двух переменных и на ее основе написать программу сортировки массива (будем использовать сортировку пузырьком).
Описание шаблонного класса «пара»
Описание шаблонного класса для подсчёта суммы чисел
Шаблонная функция, которая меняет местами значения двух переменных
Допустим, у нас есть функция, которая меняет местами значения двух переменных типа int:
#include <iostream>
void my_swap (int & first, int & second)
{
int temp (first);
first = second;
second = temp;
}
int main ()
{
int a = 5;
int b = 10;
cout << a << " " << b << endl;
my_swap (a, b);
cout << a << " " << b << endl;
}
Теперь нам необходимо обменять значения переменных типа double. Функция для обмена значений двух переменных типа int нам не подойдет. Напишем функцию для double:
void my_swap (double & first, double & second)
{
double temp (first);
first = second;
second = temp;
}
Как видите, у нас алгоритм абсолютно одинаковый, отличаются лишь типы параметров и тип переменной temp. А теперь представьте, что нам еще нужны функции для short, long double, char, string и еще множества других типов. Конечно, можно просто скопировать первую функцию, и исправить типы на нужные, тогда получим новую функцию с необходимыми типами. А если функция будет не такая простая? Избежать всего этого помогут шаблоны.
Теперь напишем шаблонную функцию my_swap. Исходя из структуры объявления шаблона следует, что наша функция будет выглядеть так:
template <параметры_шаблона> описание_функции.
Напишем функцию:
template < typename T>
void my_swap (T & first, T & second) //T - тип, указанный в параметре шаблона
{
T temp (first);
first = second;
second = temp;
}
// The one and only application object
//======================================
void main1();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule =::GetModuleHandle(NULL);
if (hModule!= NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL,::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
main1();
system("Pause");
}
}
else
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}
return nRetCode;
}
Результат:
Модифицируем эту программу для сортировки массива, в котором могут быть числа разных типов.
CWinApp theApp;
using namespace std;
void main1();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule =::GetModuleHandle(NULL);
if (hModule!= NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL,::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
Else
{
// TODO: code your application's behavior here.
main1();
system("Pause");
}
}
Else
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}
return nRetCode;
}
Результат: