Hvordan bruke C ++ maler

Hvordan bruke C ++ maler
I grunnleggende C ++ programmering, datatypen, e.g., int eller røye, må angis i en erklæring eller en definisjon. En verdi som 4 eller 22 eller -5 er en int. En verdi som 'A' eller 'B' eller 'C' er en røye. Malmekanismen lar programmereren bruke en generisk type for et sett med faktiske typer. For eksempel kan programmereren bestemme seg for å bruke identifikatoren T for Int eller Char. Det er mulig for en C ++ -algoritme å ha mer enn en generisk type. Med, for eksempel, T for int eller røye, kan du stå for float- eller pekertypen. En klasse, for eksempel strengen eller vektorklassen, er som en datatype, og de instantierte objektene er som verdier av datatypen, som er den spesifiserte klassen. Så malmekanismen lar også programmereren bruke en generisk type identifikator for et sett med klasser.

En C ++ -mal oppretter en algoritme uavhengig av typen som brukes. Så den samme algoritmen, med mange forekomster av samme type, kan bruke forskjellige typer ved forskjellige henrettelser. Enhetene med variabel, funksjon, struktur og klasse kan ha maler. Denne artikkelen forklarer hvordan du erklærer maler, hvordan du kan definere maler og hvordan du bruker dem i C++. Du bør allerede ha kunnskap om de nevnte enhetene for å forstå temaene som dekkes i denne artikkelen.

Typer

Skalar

Skalartypene er tomrom, bool, røye, int, float og peker.

Klasser som typer

En bestemt klasse kan betraktes som en type og dens objekter som mulige verdier.

En generisk type representerer et sett av skalartyper. Listen over skalartyper er omfattende. INT -typen har for eksempel andre relaterte typer, for eksempel kort int, lang int, etc. En generisk type kan også representere et sett med klasser.

Variabel

Et eksempel på en malerklæring og definisjon er som følger:

mal T pi = 3.14;

Før du fortsetter, må du merke deg at denne typen uttalelser ikke kan vises i hovedfunksjonen () eller et hvilket som helst blokkomfang. Den første linjen er mal-head-erklæringen, med den programmerer-valgte generiske typenavn, t. Neste linje er definisjonen av identifikatoren, Pi, som er av den generiske typen, t. Presisjon, om T er en int eller en flottør eller annen type, kan gjøres i C ++ Main () -funksjonen (eller annen funksjon). Slik presisjon vil bli gjort med variabel PI, og ikke t.

Den første linjen er maldeklarasjonen. Denne erklæringen begynner med det reserverte ordet, malen og deretter de åpne og lukkede vinkelbrakettene. Innenfor vinkelbrakettene er det minst en generisk type identifikator, for eksempel T, ovenfor. Det kan være mer enn en generisk type identifikator, med hver foregått av det reserverte ordet, typenavn. Slike generiske typer i den posisjonen kalles malparametere.

Følgende uttalelse kan skrives i Main () eller i noen annen funksjon:

cout << pi << '\n';

Og funksjonen ville vise 3.14. Uttrykket Pi bestemmer den nøyaktige typen T for variabel PI. Spesialisering bestemmer den aktuelle datatypen for malparameteren. Instantiation er den interne prosessen med C ++. Ikke forveksle mellom å installere en malparameter og instantiere en klasse. I malemnet kan mange datatyper ha ett generisk type-navn, mens mange klasser kan ha ett generisk klassenavn. Imidlertid blir det generiske klassenavnet for klasser ganske enkelt referert til som en klasse, og ikke som et klassenavn. En verdi er også for en datatype, for eksempel Int, som et instantiert objekt er for en klasse, for eksempel strengklassen.

Ved spesialisering er den valgte datatypen, for eksempel float, plassert i vinkelfester etter variabelen. Hvis det er mer enn en malparameter i mal-head-erklæringen, vil det være et tilsvarende antall datatyper i samme rekkefølge i spesialiseringsuttrykket.

Ved spesialisering er en type kjent som et malargument. Ikke forveksle mellom dette og funksjonsargumentet for funksjonsanrop.

Standardtype

Hvis ingen type er gitt ved spesialisering, antas standardtypen. Så fra følgende uttrykk:

mal U pi = "kjærlighet";

Denne kammen brukes som sådan med en standardtype:

cout << pi << '\n';

Hvorved "kjærlighet" for den konstante pekeren til Char brukes som standard fra malen. Merk i erklæringen at u = const char*. Vinkelbrakettene vil være tomme ved spesialisering (ingen type gitt); Selve typen regnes som en const -peker til Char, standardtypen. Hvis det var nødvendig. Når standardtypen er ønsket ved spesialisering, er det valgfritt å gjenta typen i vinkelbrakettene, i.e., Vinkelbrakettene kan være tomme.

Merk: Standardtypen kan fortsatt endres ved spesialisering ved å ha en annen type.

struktur

Følgende eksempel viser hvordan en malparameter kan brukes med en struktur:

mal Struktur aldre

T John = 11;
T Peter = 12;
T Mary = 13;
T Joy = 14;
;

Dette er aldre av elever i klasse (klasse). Den første linjen er malerklæringen. Kroppen i seler er den faktiske definisjonen av malen. Aldrene kan sendes ut i hovedfunksjonen () med følgende:

Aldre Grad7;
cout << grade7.John << " << grade7.Mary << '\n';

Utgangen er: 11 13. Den første uttalelsen her utfører spesialiseringen. Legg merke til hvordan det er blitt laget. Det gir også et navn for et objekt av strukturen: grad7. Den andre uttalelsen har ordinære strukturobjektuttrykk. En struktur er som en klasse. Her er aldre som et klassenavn, mens klasse7 er et objekt for klassen (struct).

Hvis noen aldre er heltall og andre er flyter, trenger strukturen to generiske parametere, som følger:

mal Struktur aldre

T John = 11;
U peter = 12.3;
T Mary = 13;
U Joy = 14.6;
;

En relevant kode for Main () -funksjonen er som følger:

Aldre Grad7;
cout << grade7.John << " << grade7.Peter << '\n';

Utgangen er: 11 12.3. Ved spesialisering må rekkefølgen på typene (argumenter) samsvare med rekkefølgen på de generiske typene i erklæringen.

Malerklæringen kan skilles fra definisjonen, som følger:

mal Struktur aldre

T John;
U peter;
T Mary;
U glede;
;
Aldre klasse7 = 11, 12.3, 13, 14.6;

Det første kodesegmentet er rent en erklæring om en mal (det er ingen oppgaver). Det andre kodesegmentet, som bare er en uttalelse, er definisjonen av identifikatoren, grad7. Venstre side er erklæringen om identifikatoren, grad7. Høyre side er initialisatorlisten, som tildeler tilsvarende verdier til Struct-medlemmene. Det andre segmentet (uttalelsen) kan skrives i hovedfunksjonen (), mens det første segmentet forblir utenfor hovedfunksjonen ().

Ikke-type

Eksempler på ikke-datatyper inkluderer int, peker til objekt, peker til funksjon og biltyper. Det er andre ikke-typer, som denne artikkelen ikke tar opp. En ikke-type er som en ufullstendig type, hvis verdi er gitt senere og kan ikke endres. Som parameter begynner den med en bestemt ikke-type, etterfulgt av en identifikator. Verdien av identifikatoren er gitt senere, ved spesialisering, og kan ikke endres igjen (som en konstant, hvis verdi er gitt senere). Følgende program illustrerer dette:

#inkludere
ved hjelp av navneområdet STD;
mal Struktur aldre

T John = n;
U peter = 12.3;
T Mary = n;
U Joy = 14.6;
;
int main ()

Aldre Grad7;
cout << grade7.John << " << grade7.Joy << '\n';
retur 0;

Ved spesialisering er den første typen, Int, i vinkelbrakettene, mer for formalitet, for å sikre at antall og rekkefølge på parametere tilsvarer antallet og rekkefølgen på typer (argumenter). Verdien av n er gitt ved spesialisering. Utgangen er: 11 14.6.

Delvis spesialisering

La oss anta at en mal har fire generiske typer, og at det blant de fire typene er behov for to standardtyper. Dette kan oppnås ved bruk av den delvise spesialiseringskonstruksjonen, som ikke bruker tildelingsoperatøren. Så den delvise spesialiseringskonstruksjonen gir standardverdier til en delmengde av generiske typer. Imidlertid er det nødvendig med en delvis spesialiseringsskjema. Følgende program illustrerer dette for en generisk type av to generiske typer:

#inkludere
ved hjelp av navneområdet STD;
// base malklasse
mal
Struktur aldre

;
// Delvis spesialisering
mal
Struktur aldre

T1 John = 11;
Float Peter = 12.3;
T1 Mary = 13;
Float Joy = 14.6;
;
int main ()

Aldre Grad7;
cout << grade7.John << " << grade7.Joy << '\n';
retur 0;

Identifiser grunnklasse erklæringen og dens definisjon av delvis klasse. Malhode-erklæringen fra baseklassen har alle nødvendige generiske parametere. Malhode-erklæringen fra den delvise spesialiseringsklassen har kun den generiske typen. Det er et ekstra sett med vinkelbraketter som brukes i ordningen som kommer like etter navnet på klassen i den delvise spesialiseringsdefinisjonen. Det er det som faktisk gjør den delvise spesialiseringen. Den har standardtypen og ikke-default-typen, i den rekkefølgen skrevet i baseklassen. Merk at standardtypen fremdeles kan gis en annen type i hovedfunksjonen ().

Den aktuelle koden i hoved- () -funksjonen kan være som følger:

Aldre Grad7;
cout << grade7.John << " << grade7.Joy << '\n';

Utgangen er: 11 14.6.

Malparameterpakke

En parameterpakke er en malparameter som godtar null eller flere malens generiske typer for de tilsvarende datatypene. Parameterpakkeparameteren begynner med det reserverte ordet typisk eller klassen. Dette blir fulgt av tre prikker, og deretter identifikatoren for pakken. Følgende program illustrerer hvordan en malparameterpakke kan brukes med en struktur:

#inkludere
ved hjelp av navneområdet STD;
mal Struktur aldre

int John = 11;
Float Peter = 12.3;
Int Mary = 13;
Float Joy = 14.6;
;
int main ()

Aldre Gradb;
cout << gradeB.John << " << gradeB.Mary << '\n';
Aldre gradec;
cout << gradeC.Peter << " << gradeC.Joy << '\n';
Aldre gradert;
cout << gradeD.John << " << gradeD.Joy << '\n';
Aldre gradea; // som standard
cout << gradeA.John << " << gradeA.Joy << '\n';
retur 0;

Utgangen er:

11 13
12.3 14.6
11 14.6
11 14.6

Funksjonsmaler

Malfunksjonene nevnt ovenfor gjelder på en lignende måte som funksjonsmaler. Følgende program viser en funksjon med to generiske malparametere og tre argumenter:

#inkludere
ved hjelp av navneområdet STD;
mal void func (t nei, u cha, const char *str)
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()
func (12, '$', "500");
retur 0;

Utgangen er som følger:

Det er 12 bøker til en verdi av $ 500 i butikken.

Separasjon fra prototype

Funksjonsdefinisjonen kan skilles fra prototypen, som følgende program viser:

#inkludere
ved hjelp av navneområdet STD;
mal void func (t nei, u cha, const char *str);
mal void func (t nei, u cha, const char *str)
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()
func (12, '$', "500");
retur 0;

Merk: Funksjonsmalens erklæring kan ikke vises i hovedfunksjonen () eller i noen annen funksjon.

Overbelastning

Overbelastning av den samme funksjonen kan finne sted med forskjellige malhode-erklæringer. Følgende program illustrerer dette:

#inkludere
ved hjelp av navneområdet STD;
mal void func (t nei, u cha, const char *str)
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

mal void func (t nei, const char *str)
cout << "There are " << no << " books worth $" << str << " in the store." << '\n';

int main ()

func (12, '$', "500");
func (12, "500");
retur 0;

Utgangen er:

Det er 12 bøker til en verdi av $ 500 i butikken.

Det er 12 bøker til en verdi av $ 500 i butikken.

Klassemaler

Funksjonene til malene nevnt ovenfor gjelder på lignende måte som klassemaler. Følgende program er erklæringen, definisjonen og bruken av en enkel klasse:

#inkludere
ved hjelp av navneområdet STD;
Klasse thecla

offentlig:
int num;
statisk char ch;
void func (char cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

statisk tomrom (char ch)
if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

Thecla obj;
obj.num = 12;
obj.func ('$', "500");
retur 0;

Utgangen er som følger:

Det er 12 bøker til en verdi av $ 500 i butikken.

Følgende program er ovennevnte program med en mal-head-erklæring:

#inkludere
ved hjelp av navneområdet STD;
mal Klasse thecla

offentlig:
T num;
statisk u ch;
void func (u cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

statisk tomrom (u ch)
if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

Thecla obj;
obj.num = 12;
obj.func ('$', "500");
retur 0;

I stedet for ordet typisk navn i malparameterlisten, kan ordklassen brukes. Legg merke til spesialiseringen i erklæringen til objektet. Utgangen er fortsatt den samme:

Det er 12 bøker til en verdi av $ 500 i butikken.

Skille erklæring

Klassemalerklæringen kan skilles fra klassekoden, som følger:

mal klasse thecla;
mal Klasse thecla
offentlig:
T num;
statisk u ch;
void func (u cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

statisk tomrom (u ch)
if (ch == 'a')
cout << "Official static member function" << '\n';

;

Håndtere statiske medlemmer

Følgende program viser hvordan du får tilgang til et statisk datamedlem og en statisk medlemsfunksjon:

#inkludere
ved hjelp av navneområdet STD;
mal Klasse thecla
offentlig:
T num;
statisk u ch;
void func (u cha, const char *str)
cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

statisk tomrom (u cha)
if (ch == 'a')
cout << "Official static member function" << cha << '\n';

;
mal U thecla:: ch = 'a';
int main ()

Thecla::moro('.');
retur 0;

Å tildele en verdi til et statisk datamedlem er en erklæring og kan ikke være i Main (). Legg merke til bruken og posisjonene til de generiske typene og den generiske typen data i tildelingsuttalelsen. I tillegg må du merke deg at den statiske datamedlemmet er kalt i Main (), med de faktiske maldatatypene. Utgangen er følgende:

Offisiell statisk medlemsfunksjon.

Kompilere

Erklæringen (overskriften) og definisjonen av en mal må være i en fil. Det vil si at de må være i samme oversettelsesenhet.

Konklusjon

C ++ maler gjør en algoritme uavhengig av typen som brukes. Enhetene med variabel, funksjon, struktur og klasse kan ha maler, som involverer erklæring og definisjon. Å lage en mal innebærer også spesialisering, og det er når en generisk type tar en faktisk type. Erklæringen og definisjonen av en mal må begge være i en oversettelsesenhet.