W tym artykule dowiesz się o szablonach w C ++. Nauczysz się wykorzystywać możliwości szablonów do programowania ogólnego.
Szablony to zaawansowane funkcje języka C ++, które pozwalają na pisanie ogólnych programów. Mówiąc najprościej, możesz utworzyć pojedynczą funkcję lub klasę do pracy z różnymi typami danych przy użyciu szablonów.
Szablony są często używane w większej bazie kodu w celu ponownego wykorzystania kodu i elastyczności programów.
Koncepcji szablonów można używać na dwa różne sposoby:
- Szablony funkcji
- Szablony klas
Szablony funkcji
Szablon funkcji działa podobnie do zwykłej funkcji, z jedną kluczową różnicą.
Pojedynczy szablon funkcji może działać jednocześnie z różnymi typami danych, ale pojedyncza normalna funkcja może działać tylko z jednym zestawem typów danych.
Zwykle, jeśli musisz wykonać identyczne operacje na dwóch lub więcej typach danych, użyj przeciążenia funkcji, aby utworzyć dwie funkcje z wymaganą deklaracją funkcji.
Jednak lepszym podejściem byłoby użycie szablonów funkcji, ponieważ można wykonać to samo zadanie, pisząc mniej kodu, który można konserwować.
Jak zadeklarować szablon funkcji?
Szablon funkcji zaczyna się od szablonu słowa kluczowego, po którym następuje parametr / y szablonu, po których następuje deklaracja funkcji.
szablon < klasa T> T someFunction (T arg) (…)
W powyższym kodzie T jest argumentem szablonu, który akceptuje różne typy danych (int, float), a class to słowo kluczowe.
W typename
powyższym przykładzie możesz również użyć słowa kluczowego zamiast class.
Gdy przekazywany jest argument typu danych someFunction( )
, kompilator generuje nową wersję someFunction()
dla danego typu danych.
Przykład 1: Szablon funkcji do znalezienia największej liczby
Program do wyświetlania największej z dwóch liczb za pomocą szablonów funkcji.
// 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; )
Wynik
Wpisz dwie liczby całkowite: 5 10 10 jest większe. Wpisz dwie liczby zmiennoprzecinkowe: 12,4 10,2 12,4 jest większe. Wpisz dwa znaki: z Z z ma większą wartość ASCII.
W powyższym programie Large()
zdefiniowano szablon funkcji, który przyjmuje dwa argumenty n1 i n2 typu danych T
. T
oznacza, że argument może być dowolnego typu danych.
Large()
funkcja zwraca największy z dwóch argumentów przy użyciu prostej operacji warunkowej.
Wewnątrz main()
funkcji, zmienne z trzech różnych typów danych: int
, float
i char
są zgłaszane. Zmienne są następnie przekazywane do Large()
szablonu funkcji jako normalne funkcje.
W czasie wykonywania, gdy liczba całkowita jest przekazywana do funkcji szablonu, kompilator wie, że musi wygenerować Large()
funkcję, która zaakceptuje argumenty int, i robi to.
Podobnie, gdy przekazywane są dane zmiennoprzecinkowe i dane typu char, zna argumentowe typy danych i odpowiednio generuje Large()
funkcję.
W ten sposób użycie tylko jednego szablonu funkcji zastąpiło trzy identyczne normalne funkcje i umożliwiło utrzymanie kodu.
Przykład 2: Zamiana danych za pomocą szablonów funkcji
Program do wymiany danych za pomocą szablonów funkcji.
#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; )
Wynik
Przed przekazaniem danych do szablonu funkcji. i1 = 1 i2 = 2 f1 = 1,1 f2 = 2,2 c1 = a c2 = b Po przekazaniu danych do szablonu funkcji. i1 = 2 i2 = 1 f1 = 2,2 f2 = 1,1 c1 = b c2 = a
W tym programie zamiast wywoływać funkcję przez przekazanie wartości, wywoływane jest odwołanie.
Swap()
Szablon funkcja przyjmuje dwa argumenty i swapy nich przez odniesienie.
Szablony klas
Podobnie jak szablony funkcji, można również tworzyć szablony klas dla ogólnych operacji na klasach.
Czasami potrzebna jest implementacja klasy, która jest taka sama dla wszystkich klas, tylko używane typy danych są różne.
Zwykle należałoby utworzyć inną klasę dla każdego typu danych LUB utworzyć różne zmienne składowe i funkcje w ramach jednej klasy.
Spowoduje to niepotrzebne rozdęcie bazy kodu i będzie trudne do utrzymania, ponieważ zmiana dotyczy jednej klasy / funkcji, która powinna zostać wykonana na wszystkich klasach / funkcjach.
Jednak szablony klas ułatwiają ponowne użycie tego samego kodu dla wszystkich typów danych.
Jak zadeklarować szablon klasy?
template < class T> class className (… public: T var; T someOperation (T arg);…);
W powyższej deklaracji T
jest argumentem szablonu, który jest symbolem zastępczym dla używanego typu danych.
W treści klasy zmienna składowa var i funkcja składowa someOperation()
są typu T
.
Jak stworzyć obiekt szablonu klasy?
Aby utworzyć obiekt szablonu klasy, podczas tworzenia należy zdefiniować typ danych wewnątrz a .
className classObject;
Na przykład:
className classObject; className classObject; className classObject;
Przykład 3: Prosty kalkulator korzystający z szablonu klasy
Program do dodawania, odejmowania, mnożenia i dzielenia dwóch liczb za pomocą szablonu klasy
#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; )
Wynik
Wyniki całkowite: Liczby to: 2 i 1. Dodawanie to: 3 Odejmowanie to: 1 Iloczyn to: 2 Dzielenie to: 2 Wyniki typu float: Liczby to: 2,4 i 1,2. Dodawanie wynosi: 3,6 Odejmowanie wynosi: 1,2 Iloczyn to: 2,88 Dzielenie to: 2
W powyższym programie Calculator
deklarowany jest szablon klasy .
Klasa zawiera dwóch prywatnych członków typu T
: num1 i num2 oraz konstruktora do inicjalizacji członków.
Zawiera również publiczne funkcje członkowskie do obliczania dodawania, odejmowania, mnożenia i dzielenia liczb, które zwracają wartość typu danych zdefiniowanego przez użytkownika. Podobnie funkcja displayResult()
wyświetlania ostatecznego wyniku na ekranie.
W main()
funkcji dwa różne Calculator
obiekty intCalc
i floatCalc
są tworzone dla typów danych: int
i float
odpowiednio. Wartości są inicjowane przy użyciu konstruktora.
Zauważ, że używamy i
podczas tworzenia obiektów. Informują one kompilator o typie danych użytym do utworzenia klasy.
Spowoduje to utworzenie definicji klasy dla int
i float
, które są następnie odpowiednio używane.
Następnie displayResult()
wywoływany jest oba obiekty, który wykonuje operacje kalkulatora i wyświetla wynik.