В этой статье вы узнаете о шаблонах в C ++. Вы научитесь использовать возможности шаблонов для общего программирования.
Шаблоны - это мощные возможности C ++, которые позволяют писать общие программы. Проще говоря, вы можете создать одну функцию или класс для работы с разными типами данных с помощью шаблонов.
Шаблоны часто используются в более крупной кодовой базе с целью повторного использования кода и гибкости программ.
Концепцию шаблонов можно использовать двумя разными способами:
- Шаблоны функций
- Шаблоны классов
Шаблоны функций
Шаблон функции работает аналогично обычной функции, с одним ключевым отличием.
Один шаблон функции может работать с разными типами данных одновременно, но одна обычная функция может работать только с одним набором типов данных.
Обычно, если вам нужно выполнить идентичные операции с двумя или более типами данных, вы используете перегрузку функций, чтобы создать две функции с требуемым объявлением функции.
Однако лучшим подходом было бы использовать шаблоны функций, потому что вы можете выполнять ту же задачу, написав меньше кода и поддерживаемый код.
Как объявить шаблон функции?
Шаблон функции начинается с ключевого слова template, за которым следует параметр / s шаблона, за которым следует объявление функции.
template < class T> T someFunction (T arg) (…)
В приведенном выше коде T - это аргумент шаблона, который принимает разные типы данных (int, float), а class - это ключевое слово.
Вы также можете использовать ключевое слово typename
вместо класса в приведенном выше примере.
Когда аргумент типа данных передается someFunction( )
, компилятор генерирует новую версию someFunction()
для данного типа данных.
Пример 1: шаблон функции для поиска наибольшего числа
Программа для отображения наибольшего из двух чисел с использованием шаблонов функций.
// If two characters are passed to function template, character with larger ASCII value is displayed. #include using namespace std; // template function template T Large(T n1, T n2) ( return (n1> n2) ? n1 : n2; ) int main() ( int i1, i2; float f1, f2; char c1, c2; cout <> i1>> i2; cout << Large(i1, i2) <<" is larger." << endl; cout <> f1>> f2; cout << Large(f1, f2) <<" is larger." << endl; cout <> c1>> c2; cout << Large(c1, c2) << " has larger ASCII value."; return 0; )
Вывод
Введите два целых числа: 5 10 10 больше. Введите два числа с плавающей запятой: 12,4 10,2 12,4 больше. Введите два символа: z Z z имеет большее значение ASCII.
В приведенной выше программе определен шаблон функции, Large()
который принимает два аргумента n1 и n2 типа данных T
. T
означает, что аргумент может иметь любой тип данных.
Large()
Функция возвращает наибольший из двух аргументов с помощью простой условной операции.
Внутри main()
функции, переменные трех различных типов данных: int
, float
и char
объявляются. Затем переменные передаются в Large()
шаблон функции как обычные функции.
Когда во время выполнения функции шаблона передается целое число, компилятор знает, что он должен сгенерировать Large()
функцию для принятия аргументов типа int, и делает это.
Точно так же, когда передаются данные с плавающей запятой и данные char, он знает типы данных аргументов и соответственно генерирует Large()
функцию.
Таким образом, использование только одного шаблона функции заменяет три идентичные обычные функции и делает ваш код поддерживаемым.
Пример 2: Обмен данными с использованием шаблонов функций
Программа для обмена данными с использованием шаблонов функций.
#include using namespace std; template void Swap(T &n1, T &n2) ( T temp; temp = n1; n1 = n2; n2 = temp; ) int main() ( int i1 = 1, i2 = 2; float f1 = 1.1, f2 = 2.2; char c1 = 'a', c2 = 'b'; cout << "Before passing data to function template."; cout << "i1 = " << i1 << "i2 = " << i2; cout << "f1 = " << f1 << "f2 = " << f2; cout << "c1 = " << c1 << "c2 = " << c2; Swap(i1, i2); Swap(f1, f2); Swap(c1, c2); cout << "After passing data to function template."; cout << "i1 = " << i1 << "i2 = " << i2; cout << "f1 = " << f1 << "f2 = " << f2; cout << "c1 = " << c1 << "c2 = " << c2; return 0; )
Вывод
Перед передачей данных в шаблон функции. i1 = 1 i2 = 2 f1 = 1,1 f2 = 2,2 c1 = a c2 = b После передачи данных в шаблон функции. i1 = 2 i2 = 1 f1 = 2.2 f2 = 1.1 c1 = b c2 = a
В этой программе вместо вызова функции путем передачи значения выполняется вызов по ссылке.
Swap()
Шаблон функции принимает два аргумента и свопы их по ссылке.
Шаблоны классов
Как и шаблоны функций, вы также можете создавать шаблоны классов для общих операций класса.
Иногда вам нужна реализация класса, которая одинакова для всех классов, отличаются только используемые типы данных.
Обычно вам нужно создать отдельный класс для каждого типа данных ИЛИ создать разные переменные-члены и функции в одном классе.
Это приведет к излишнему раздуванию базы кода и будет трудно поддерживать, поскольку изменение состоит в том, что один класс / функция должен выполняться для всех классов / функций.
Однако шаблоны классов позволяют легко повторно использовать один и тот же код для всех типов данных.
Как объявить шаблон класса?
шаблон < класс T> class className (… public: T var; T someOperation (T arg);…);
В приведенном выше объявлении T
- это аргумент шаблона, который является заполнителем для используемого типа данных.
Внутри тела класса переменная-член var и функция-член someOperation()
имеют тип T
.
Как создать объект шаблона класса?
Чтобы создать объект шаблона класса, вам необходимо определить тип данных внутри при создании.
className classObject;
Например:
className classObject; className classObject; className classObject;
Пример 3: Простой калькулятор с использованием шаблона класса
Программа для сложения, вычитания, умножения и деления двух чисел с использованием шаблона класса
#include using namespace std; template class Calculator ( private: T num1, num2; public: Calculator(T n1, T n2) ( num1 = n1; num2 = n2; ) void displayResult() ( cout << "Numbers are: " << num1 << " and " << num2 << "." << endl; cout << "Addition is: " << add() << endl; cout << "Subtraction is: " << subtract() << endl; cout << "Product is: " << multiply() << endl; cout << "Division is: " << divide() << endl; ) T add() ( return num1 + num2; ) T subtract() ( return num1 - num2; ) T multiply() ( return num1 * num2; ) T divide() ( return num1 / num2; ) ); int main() ( Calculator intCalc(2, 1); Calculator floatCalc(2.4, 1.2); cout << "Int results:" << endl; intCalc.displayResult(); cout << endl << "Float results:" << endl; floatCalc.displayResult(); return 0; )
Вывод
Результаты Int: Числа: 2 и 1. Сложение: 3 Вычитание: 1 Продукт: 2 Деление: 2 Результаты с плавающей запятой: Числа: 2,4 и 1,2. Сложение: 3,6. Вычитание: 1,2. Произведение: 2,88. Деление: 2.
В приведенной выше программе объявлен шаблон класса Calculator
.
Класс содержит два закрытых члена типа T
num1 и num2 и конструктор для инициализации членов.
Он также содержит общедоступные функции-члены для вычисления сложения, вычитания, умножения и деления чисел, которые возвращают значение типа данных, определенного пользователем. Точно так же функция displayResult()
для отображения окончательного вывода на экран.
В main()
функции созданы два разных Calculator
объекта intCalc
и floatCalc
для типов данных: int
и float
соответственно. Значения инициализируются с помощью конструктора.
Обратите внимание, что мы используем и
при создании объектов. Они сообщают компилятору тип данных, используемый для создания класса.
Это создает определение класса для каждого int
и float
, которое затем используется соответствующим образом.
Затем displayResult()
вызывается из обоих объектов, который выполняет операции калькулятора и отображает результат.