templates c with examples
Lær de forskellige aspekter af skabeloner i C ++.
Skabeloner er en af de mest kraftfulde funktioner i C ++. Skabeloner giver os den kode, der er uafhængig af datatypen.
Med andre ord kan vi ved hjælp af skabeloner skrive en generisk kode, der fungerer på enhver datatype. Vi skal bare videregive datatypen som en parameter. Denne parameter, der passerer datatypen, kaldes også et typenavn.
I denne vejledning vil vi udforske alt om skabeloner og dens forskellige aspekter i detaljer.
=> Klik her for den absolutte C ++ træningsserie.
Hvad du vil lære:
hvordan man finder apk-filer på Android-telefonen
- Hvad er skabeloner?
- Sådan bruges skabeloner / implementering?
- typenavn Vs. klasse nøgleord
- Skabeloninstantiering og specialisering
- Skabelonspecialisering
- C ++ variabel skabeloner
- Konklusion
- Anbefalet læsning
Hvad er skabeloner?
Som nævnt ovenfor er skabeloner generiske, dvs. uafhængige af datatypen. Skabeloner bruges primært til at sikre programmerne genanvendelighed og fleksibilitet. Vi kan bare oprette en simpel funktion eller en klasse, der tager datatypen som parameter og implementerer den kode, der fungerer for enhver datatype.
For eksempel, hvis vi vil have en sorteringsalgoritme til at arbejde for alle numeriske datatyper såvel som tegnstrenge, så skriver vi bare en funktion, der tager datatypen som et argument og implementerer sorteringsteknikken.
Afhængigt af den datatype (typenavn), der sendes til sorteringsalgoritmen, kan vi sortere dataene uanset datatypen. På denne måde behøver vi ikke skrive ti algoritmer til ti datatyper.
Således kan skabeloner bruges i applikationer, hvor vi kræver, at koden skal kunne bruges til mere end én datatype. Skabeloner bruges også i applikationer, hvor genanvendelighed af kode er af største betydning.
Sådan bruges skabeloner / implementering?
Skabeloner kan implementeres på to måder:
- Som en funktionsskabelon
- Som en klasseskabelon
Funktionsskabelon
Funktionsskabelon er ligesom en normal funktion, men den eneste forskel er, at normal funktion kun kan arbejde på en datatype, og en funktionsskabelonkode kan arbejde på flere datatyper.
Mens vi faktisk kan overbelaste en normal funktion til at arbejde på forskellige datatyper, er funktionsskabeloner altid mere nyttige, da vi er nødt til at skrive det eneste program, og det kan fungere på alle datatyper.
Dernæst vil vi se implementeringen af funktionsskabeloner.
Den generelle syntaks for funktionsskabelonen er:
template T function_name(T args){ …… //function body }
Her er T skabelonargumentet, der accepterer forskellige datatyper, og klasse er et nøgleord. I stedet for nøgleordsklassen kan vi også skrive 'typenavn'.
Når en bestemt datatype sendes til funktionsnavn, laves en kopi af denne funktion af compileren med denne datatype som argument, og funktionen udføres.
Lad os se et eksempel for bedre at forstå funktionsskabeloner.
#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<Klasseskabeloner Som i funktionsskabeloner har vi muligvis et krav om at have en klasse, der ligner alle andre aspekter, men kun forskellige datatyper.
I denne situation kan vi have forskellige klasser for forskellige datatyper eller forskellige implementeringer for forskellige datatyper i samme klasse. Men at gøre dette vil gøre vores kode voluminøs.
Den bedste løsning til dette er at bruge en skabelonklasse. Skabelonklassen opfører sig også som funktionsskabeloner. Vi er nødt til at videregive datatypen som en parameter til klassen, mens vi opretter objekter eller kalder medlemsfunktioner.
Den generelle syntaks for klasseskabelonen er:
template class className{ ….. public: T memVar; T memFunction(T args); };
I ovenstående definition fungerer T som en pladsholder for datatypen. De offentlige medlemmers memVar og memFunction bruger også T som pladsholder til datatyper.
Når en skabelonklasse er defineret som ovenfor, kan vi oprette klasseobjekter som følger:
className classObejct1; className classObject2; className classObject3;
Lad os implementere et kodeeksempel for at demonstrere klasseskabeloner:
#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 = '< Produktion:
Maksimum på 100 og 75 = 100
Maksimum på 'A' og 'a' = a
Ovenstående program implementerer et eksempel på en klasseskabelon. Vi har skabelonklassen myclass. Inde i dette har vi en konstruktør, der initialiserer de to medlemmer a og b i klassen. Der er en anden medlemsfunktion getMaxval, som også er en funktionsskabelon, der maksimalt returnerer a og b.
I hovedfunktionen konstruerer vi to objekter, myobject af typen heltal og mychobject af typen karakter. Derefter kalder vi getMaxval-funktionen på hvert af disse objekter for at bestemme den maksimale værdi.
Bemærk, at bortset fra skabelontypeparametre (parametre af type T), kan skabelonfunktioner også have almindelige parametre som normale funktioner og også standardparameterværdier.
typenavn Vs. klasse nøgleord
Mens vi erklærer skabelonklasse eller funktion, bruger vi et af de to nøgleordsklasse eller typenavn. Disse to ord er semantisk ækvivalente og kan bruges om hverandre.
Men i nogle tilfælde kan vi ikke bruge disse ord som ækvivalente. For eksempel, når vi bruger afhængige datatyper i skabeloner som “typedef”, bruger vi typenavn i stedet for klasse.
Klassenøgleordet skal også bruges, når vi eksplicit skal instansere en skabelon.
Skabeloninstantiering og specialisering
Skabelonerne er skrevet på en generisk måde, hvilket betyder, at det er en generel implementering uanset datatypen. I henhold til den angivne datatype skal vi generere en konkret klasse for hver datatype.
For eksempel, hvis vi har en skabelonsorteringsalgoritme, kan vi generere en konkret klasse til sortering, en anden klasse til sortering osv. Dette kaldes instantiering af skabelonen.
Vi erstatter skabelonargumenterne (faktiske datatyper) med skabelonparametrene i definitionen af skabelonklassen.
For eksempel,
template class sort {};
Når vi videregiver datatype, erstatter kompilatoren datatypen med 'T', så sorteringsalgoritmen bliver sorteret.
Hver gang når vi bruger skabelonklasse eller funktion, er der behov for en forekomst, når vi videregiver en bestemt datatype. Hvis denne forekomst ikke allerede er til stede, opretter kompilatoren en med den specifikke datatype. Dette er den implicitte instantiering.
En ulempe ved implicit instantiering er, at kompilatoren kun genererer instansklasse for de argumenter, der bruges i øjeblikket. Dette betyder, at hvis vi vil generere et bibliotek med forekomster inden brugen af disse forekomster, er vi nødt til at gå til eksplicit instantiering.
Et eksempel på skabelondeklaration er givet nedenfor:
template class Array(T)
Kan udtrykkeligt instantieres som:
template class Array
Når en klasse instantieres, instantieres alle dens medlemmer også.
Skabelonspecialisering
Når vi programmerer ved hjælp af skabeloner, kan vi blive stillet over for en sådan situation, at vi muligvis kræver en særlig implementering af en bestemt datatype. Når en sådan situation opstår, går vi til skabelonspecialisering.
I skabelonspecialisering implementerer vi en særlig opførsel for en bestemt datatype bortset fra den originale skabelondefinition for de andre datatyper.
For eksempel, overvej, at vi har en skabelonklasse minIncrement ' som har en konstruktør til at initialisere en værdi og en skabelonfunktion tilIncrement der øger værdien med 1.
Denne særlige klasse fungerer perfekt for alle datatyper undtagen char. I stedet for at øge værdien for char, hvorfor ikke give den en særlig opførsel og konvertere tegnet til store bogstaver i stedet?
For at gøre dette kan vi gå til skabelonspecialisering for char-datatypen.
Denne implementering er vist i nedenstående kodeeksempel.
#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: '< Produktion:
Forhøjet int-værdi: 8
Stor bogstav: S
Forhøjet dobbeltværdi: 12
I ovenstående program, der demonstrerer skabelonspecialisering, se den måde, hvorpå vi har erklæret en specialskabelon til char-type. Vi erklærer først den oprindelige klasse, og derefter ”specialiserer” vi den til char-type. For at begynde specialisering bruger vi tom skabelondeklaration 'skabelon'.
Derefter inkluderer vi datatypen efter klassens navn. Efter disse to ændringer skrives klassen for char-typen.
I hovedfunktionen skal du bemærke, at der ikke er nogen forskel mellem instantiering af char-type og andre typer. Den eneste forskel er, at vi omdefinerer den specialiserede klasse.
Bemærk, at vi skal definere alle medlemmerne af den specialiserede klasse, selvom de er nøjagtigt de samme i den generiske / originale skabelonklasse. Dette skyldes, at vi ikke har arvefunktion for medlemmer fra den generiske skabelon til den specialiserede skabelon.
C ++ variabel skabeloner
Indtil videre har vi set funktionsskabeloner, der tager et fast antal argumenter. Der er også skabeloner, der tager et variabelt antal argumenter. Disse funktionsskabeloner kaldes variadiske skabeloner. Variadiske skabeloner er en af de nyeste funktioner i C ++ 11.
Variadiske skabeloner tager et variabelt antal argumenter, der er typesikre, og argumenterne løses på kompileringstidspunktet.
Lad os tage et komplet programmeringseksempel for at forstå dette.
#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 = '< Ovenstående eksempel viser variadisk funktion, “summering”. Som vist ovenfor har vi først brug for en basisfunktion, der implementerer basissagen. Derefter implementerer vi den variadiske funktion øverst på denne funktion.
I summeringsvariablen kaldes 'typenavn ... args' skabelonparameterpakke mens 'Args ... args' kaldes funktionsparameterpakke .
Efter at have skrevet en funktionsskabelon, der implementerer basissagen, skriver vi en variadisk funktion, der implementerer det generelle tilfælde. Den variadiske funktion er skrevet svarende til rekursionen som vist til opsummering (args ...). Det første argument er adskilt fra funktionsparameterpakken til type T (første).
For hvert opkald til opsummering bliver parameterlisten smallere af ét argument, og til sidst nås basistilstanden. Outputtet viser summeringen for lange heltal og tegn.
Konklusion
Med dette afslutter vi denne tutorial om skabeloner i C ++. Skabeloner hjælper os med at gøre vores programmer generiske, dvs. uafhængige af typen.
Læs også = >> Vejledning til flaskeskabeloner
Generiske programmer står altid oven på de andre programmer, da vi ikke behøver at skrive separate programmer til hver datatype. Således kan udvikling af generiske typesikre programmer være et vigtigt skridt i retning af effektiv programmering.
=> Tjek dybdegående C ++ træningsvejledninger her.
Anbefalet læsning
- Pythons hovedfunktionsvejledning med praktiske eksempler
- Sådan fungerer datadrevet test (eksempler på QTP og selen)
- Multithreading i C ++ med eksempler
- Python DateTime-tutorial med eksempler
- Eksempel på testcase-skabelon med eksempler på testcase [Download]
- Klip kommando i Unix med eksempler
- Eksempelskabelon til acceptrapport med eksempler
- Unix Cat Command Syntax, indstillinger med eksempler