templates c with examples
Aflați diferitele aspecte ale șabloanelor din C ++.
Șabloanele sunt una dintre cele mai puternice caracteristici din C ++. Șabloanele ne furnizează codul care este independent de tipul de date.
Cu alte cuvinte, folosind șabloane, putem scrie un cod generic care funcționează pe orice tip de date. Trebuie doar să trecem tipul de date ca parametru. Acest parametru care trece tipul de date se mai numește și un nume de tip.
În acest tutorial, vom explora în detaliu totul despre șabloane și diferitele sale aspecte.
=> Faceți clic aici pentru seria Absolute C ++ Training.
Ce veți învăța:
- Ce sunt șabloanele?
- Cum se utilizează șabloane / implementare?
- typename Vs. cuvânt cheie de clasă
- Instantierea și specializarea șablonului
- Specializarea șablonului
- Șabloane variabile C ++
- Concluzie
- Lectură recomandată
Ce sunt șabloanele?
După cum sa menționat mai sus, șabloanele sunt generice, adică independente de tipul de date. Șabloanele sunt utilizate în principal pentru a asigura reutilizarea codului și flexibilitatea programelor. Putem crea doar o funcție simplă sau o clasă care ia tipul de date ca parametru și să implementăm codul care funcționează pentru orice tip de date.
De exemplu, dacă dorim ca un algoritm de sortare să funcționeze pentru toate tipurile de date numerice, precum și șirurile de caractere, atunci vom scrie doar o funcție care ia tipul de date ca argument și vom implementa tehnica de sortare.
Apoi, în funcție de tipul de date (numele tipului) care este trecut la algoritmul de sortare, putem avea datele sortate indiferent de tipul de date. În acest fel nu trebuie să scriem zece algoritmi pentru zece tipuri de date.
Astfel șabloanele pot fi utilizate în aplicații în care avem nevoie de cod pentru a putea fi utilizat pentru mai multe tipuri de date. Șabloanele sunt, de asemenea, utilizate în aplicații în care reutilizarea codului este de primă importanță.
Cum se utilizează șabloane / implementare?
Șabloanele pot fi implementate în două moduri:
- Ca șablon de funcție
- Ca șablon de clasă
Șablon de funcții
Funcția Șablon este la fel ca o funcție normală, dar singura diferență este că funcția normală poate funcționa doar pe un tip de date, iar un cod de șablon de funcție poate funcționa pe mai multe tipuri de date.
Deși putem supraîncărca o funcție normală pentru a lucra pe diferite tipuri de date, șabloanele de funcții sunt întotdeauna mai utile, deoarece trebuie să scriem singurul program și poate funcționa pe toate tipurile de date.
Apoi, vom vedea implementarea șabloanelor de funcții.
Sintaxa generală a șablonului de funcție este:
template T function_name(T args){ …… //function body }
Aici, T este argumentul șablon care acceptă diferite tipuri de date, iar clasa este un cuvânt cheie. În loc de clasa de cuvinte cheie, putem scrie și „typename”.
Când un anumit tip de date este trecut către nume_funcție, o copie a acestei funcții este făcută de compilator cu acest tip de date pe măsură ce se execută un argument și o funcție.
Să vedem un exemplu pentru a înțelege mai bine șabloanele de funcții.
#include using namespace std; template void func_swap(T &arg1, T &arg2) { T temp; temp = arg1; arg1 = arg2; arg2 = temp; } int main() { int num1 = 10, num2 = 20; double d1 = 100.53, d2 = 435.54; char ch1 = 'A', ch2 = 'Z'; cout << 'Original data
'; cout << 'num1 = ' << num1 << ' num2 = ' << num2<Șabloane de clasă La fel ca în șabloanele de funcții, s-ar putea să avem cerința de a avea o clasă care este similară cu toate celelalte aspecte, dar numai cu tipuri de date diferite.
În această situație, putem avea clase diferite pentru diferite tipuri de date sau implementări diferite pentru diferite tipuri de date din aceeași clasă. Dar acest lucru va face codul nostru voluminos.
Cea mai bună soluție pentru aceasta este utilizarea unei clase de șabloane. Clasa șablon se comportă, de asemenea, similar cu șabloanele de funcții. Trebuie să trecem tipul de date ca parametru către clasă în timp ce creăm obiecte sau apelăm funcții de membru.
Sintaxa generală pentru șablonul clasei este:
template class className{ ….. public: T memVar; T memFunction(T args); };
În definiția de mai sus, T acționează ca un substituent pentru tipul de date. MemVar și memFunction ale membrilor publici folosesc, de asemenea, T ca substituent pentru tipurile de date.
Odată ce o clasă de șablon este definită ca mai sus, putem crea obiecte de clasă după cum urmează:
className classObejct1; className classObject2; className classObject3;
Să implementăm un exemplu de cod pentru a demonstra șabloanele de clasă:
#include using namespace std; template class myclass { T a, b; public: myclass (T first, T second) {a=first; b=second;} T getMaxval (); }; template T myclass::getMaxval () { return (a>b? a : b); } int main () { myclass myobject (100, 75); cout<<'Maximum of 100 and 75 = '< Ieșire:
Maximum 100 și 75 = 100
Maximul „A” și „a” = a
arborele de căutare binar cod c ++
Programul de mai sus implementează un exemplu de șablon de clasă. Avem clasa șablon myclass. În interiorul acestuia, avem un constructor care va inițializa cei doi membri a și b ai clasei. Există o altă funcție membru getMaxval, care este, de asemenea, un șablon de funcție care returnează maximum a și b.
În funcția principală, construim două obiecte, myobject de tip întreg și mychobject de tip caracter. Apoi apelăm funcția getMaxval pe fiecare dintre aceste obiecte pentru a determina valoarea maximă.
Rețineți că, în afară de parametrii de tip șablon (parametrii de tip T), funcțiile șablonului pot avea și parametri obișnuiți, cum ar fi funcțiile normale și, de asemenea, valorile implicite ale parametrilor.
typename Vs. cuvânt cheie de clasă
În timp ce declarăm clasa sau funcția șablonului, folosim una dintre cele două cuvinte cheie clasă sau typename. Aceste două cuvinte sunt semantic echivalente și pot fi utilizate în mod interschimbabil.
Dar, în unele cazuri, nu putem folosi aceste cuvinte ca echivalent. De exemplu, când folosim tipuri de date dependente în șabloane precum „typedef”, folosim typename în loc de clasă.
De asemenea, cuvântul cheie de clasă trebuie utilizat atunci când trebuie să instanțiem explicit un șablon.
Instantierea și specializarea șablonului
Șabloanele sunt scrise într-un mod generic, ceea ce înseamnă că este o implementare generală, indiferent de tipul de date. Conform tipului de date furnizat, trebuie să generăm o clasă concretă pentru fiecare tip de date.
De exemplu, dacă avem un algoritm de sortare șablon, putem genera o clasă concretă pentru sortare, o altă clasă pentru sortare etc. Aceasta se numește instanțierea șablonului.
Înlocuim argumentele șablonului (tipurile de date efective) cu parametrii șablonului în definiția clasei șablonului.
De exemplu,
template class sort {};
Când trecem tipul de date, compilatorul înlocuiește tipul de date cu „T” astfel încât algoritmul de sortare să devină sort.
De fiecare dată când folosim clasa sau funcția șablonului, este nevoie de o instanță când trecem un anumit tip de date. Dacă această instanță nu este deja prezentă, compilatorul creează una cu tipul de date particular. Aceasta este instanțierea implicită.
Un dezavantaj al instanțierii implicite este că compilatorul generează clasa de instanță numai pentru argumentele utilizate în prezent. Aceasta înseamnă că, dacă dorim să generăm o bibliotecă de instanțe înainte de utilizarea acestor instanțe, trebuie să mergem pentru instanțierea explicită.
Un exemplu de declarație șablon este dat mai jos:
template class Array(T)
Poate fi instanțiat explicit ca:
template class Array
Când o clasă este instanțiată, toți membrii ei sunt, de asemenea, instanțiați.
Specializarea șablonului
În timp ce programăm folosind șabloane, ne-am putea confrunta cu o situație de așa natură încât s-ar putea să avem nevoie de o implementare specială pentru un anumit tip de date. Când apare o astfel de situație, ne îndreptăm spre specializarea șablonului.
În specializarea șablonului, implementăm un comportament special pentru un anumit tip de date, în afară de definiția șablonului original pentru celelalte tipuri de date.
De exemplu, considerăm că avem o clasă de șabloane „ myIncrement ” care are un constructor pentru a inițializa o valoare și o funcție șablon toIncrement care crește valoarea cu 1.
Această clasă specială va funcționa perfect pentru toate tipurile de date, cu excepția caracterelor. În loc să creșteți valoarea pentru char, de ce să nu-i dați un comportament special și să convertiți caracterul în majusculă?
Pentru a face acest lucru, putem alege specializarea șablonului pentru tipul de date char.
Această implementare este prezentată în exemplul de cod de mai jos.
#include using namespace std; // class template: template class myIncrement { T value; public: myIncrement (T arg) {value=arg;} T toIncrement () {return ++value;} }; // class template specialization: template class myIncrement { char value; public: myIncrement (char arg) {value=arg;} char uppercase () { if ((value>='a')&&(value<='z')) value+='A'-'a'; return value; } }; int main () { myIncrement myint (7); myIncrement mychar ('s'); myIncrement mydouble(11.0); cout<<'Incremented int value: '<< myint.toIncrement()<< endl; cout<<'Uppercase value: '< Ieșire:
Valoarea int crescută: 8
Valoare majusculă: S
Valoare dublă mărită: 12

În programul de mai sus care demonstrează specializarea șablonului, vedeți modul în care am declarat un șablon specializat pentru tipul de caracter. Mai întâi declarăm clasa originală și apoi o „specializăm” pentru tipul char. Pentru a începe specializarea folosim declarația șablon gol „șablon”.
Apoi, după numele clasei, includem tipul de date. După aceste două modificări, se scrie clasa pentru tipul char.
În funcția principală, rețineți că nu există nicio diferență între instanțierea de tip char și alte tipuri. Singura diferență este că redefinim clasa de specialitate.
Rețineți că trebuie să definim toți membrii clasei specializate, chiar dacă aceștia sunt exact aceiași în clasa șablonului generic / original. Acest lucru se datorează faptului că nu avem caracteristică de moștenire pentru membri de la șablonul generic la șablonul specializat.
Șabloane variabile C ++
Până acum am văzut șabloane de funcții care iau un număr fix de argumente. Există, de asemenea, șabloane care acceptă un număr variabil de argumente. Aceste șabloane de funcții se numesc șabloane variadice. Șabloanele variadice sunt una dintre cele mai noi caracteristici ale C ++ 11.
Șabloanele variadice iau un număr variabil de argumente care sunt sigure pentru tip, iar argumentele sunt rezolvate la compilare.
Să luăm un exemplu complet de programare pentru a înțelege acest lucru.
#include #include using namespace std; template T summation(T val) { return val; } template T summation(T first, Args... args) { return first + summation(args...); } int main() { long sum = summation(1, 2, 3, 8, 7); cout<<'Sum of long numbers = '< Exemplul de mai sus demonstrează funcția variadică, „însumare”. După cum se arată mai sus, mai întâi avem nevoie de o funcție de bază care să implementeze carcasa de bază. Apoi implementăm funcția variadică în partea de sus a acestei funcții.
În sumarea funcției variabile, se numește „typename ... args” pachetul de parametri șablon întrucât „Args ... args” se numește pachetul de parametri funcțional .
După scrierea unui șablon de funcție care implementează cazul de bază, scriem o funcție variadică care implementează cazul general. Funcția variadică este scrisă similar recursivității, așa cum se arată pentru însumare (args ...). Primul argument este separat de pachetul de parametri funcțional în tipul T (primul).
Cu fiecare apel la însumare, lista de parametri se restrânge printr-un argument și, în cele din urmă, se atinge condiția de bază. Ieșirea arată suma pentru numerele întregi și caractere lungi.
Concluzie
Cu aceasta, încheiem acest tutorial despre șabloane în C ++. Șabloanele ne ajută să facem programele noastre generice, adică independente de tip.
Citiți și = >> Tutorial șablon flacon
Programele generice stau întotdeauna deasupra celorlalte programe, deoarece nu este necesar să scriem programe separate pentru fiecare tip de date. Astfel, dezvoltarea de programe generice sigure de tip poate fi un pas important către o programare eficientă.
=> Consultați aici tutorialele de instruire în profunzime C ++.
Lectură recomandată
- Tutorial de funcții principale Python cu exemple practice
- Cum funcționează testarea bazată pe date (exemple de QTP și seleniu)
- Multithreading în C ++ cu exemple
- Tutorial Python DateTime cu exemple
- Exemplu de șablon de caz de testare cu exemple de cazuri de testare (Descărcare)
- Tăiați comanda în Unix cu exemple
- Exemplu de șablon pentru raportul testului de acceptare cu exemple
- Sintaxa de comandă Unix Cat, Opțiuni cu exemple