C ++

Hvordan bruke C ++ maler

Hvordan bruke C ++ maler

Introduksjon

I grunnleggende C ++ programmering, datatypen, e.g., int eller char, 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 char, kan U stå for flyt- eller pekertypen. En klasse, for eksempel strengen eller vektorklassen, er som en datatype, og de øyeblikkelige objektene er som verdiene for datatypen, som er den spesifiserte klassen. Malmekanismen tillater også programmereren å bruke en generisk typeidentifikator for et sett med klasser.

En C ++ mal oppretter en algoritme uavhengig av hvilken type data som brukes. Så den samme algoritmen, med mange forekomster av samme type, kan bruke forskjellige typer ved forskjellige utførelser. Enhetene av variabel, funksjon, struktur og klasse kan ha maler. Denne artikkelen forklarer hvordan man deklarerer maler, hvordan man definerer maler og hvordan man bruker dem i C++. Du bør allerede ha kunnskap om de nevnte enhetene for å forstå emnene som dekkes i denne artikkelen.

Typer

Skalar

Skalartypene er ugyldige, bool, char, 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 med skalartyper. Listen over skalartyper er omfattende. Int-typen har for eksempel andre relaterte typer, for eksempel kort int, lang int, osv. 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 at denne typen utsagn ikke kan vises i hovedfunksjonen () eller noe blokkeringsområde. Den første linjen er malhodeerklæringen, med det programmørvalgte generiske typenavnet, T. Den neste linjen er definisjonen av identifikatoren, pi, som er av generisk type, T. Presisjon, uansett om T er en int eller en flottør eller en annen type, kan gjøres i C ++ main () -funksjonen (eller en annen funksjon). Slik presisjon vil bli gjort med variabelen pi, og ikke T.

Den første linjen er malhodeerklæringen. Denne erklæringen begynner med det reserverte ordet, malen og deretter de åpne og lukkede vinkelparentene. Innenfor vinkelparentene er det minst en generisk typeidentifikator, for eksempel T, over. Det kan være mer enn en generisk typeidentifikator, med hver foran det reserverte ordet, typenavn. Slike generiske typer i den posisjonen kalles malparametere.

Følgende uttalelse kan skrives i hoved () eller i en hvilken som helst annen funksjon:

cout << pi << '\n';

Og funksjonen vil vise 3.14. Uttrykket pi bestemmer den eksakte typen T for variabelen pi. Spesialisering bestemmer den spesifikke datatypen for malparameteren. Instantiering er C ++ intern prosess for å lage den bestemte typen, for eksempel float, i dette tilfellet. Ikke forveksle mellom å starte en malparameter og å starte en klasse. I malemnet kan mange datatyper ha ett generisk typenavn, 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å til en datatype, for eksempel int, som et instantiert objekt er til en klasse, for eksempel String-klassen.

Ved spesialisering plasseres den valgte datatypen, for eksempel float, i vinkelparenteser etter variabelen. Hvis det er mer enn én malparameter i malhodeerklæ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.

Standard type

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

mal
U pi = "kjærlighet";
skjermen fra:
cout << pi<> << '\n';

er "kjærlighet" for den konstante pekeren til røye. Merk i erklæringen at U = const char *. Vinkelparentene vil være tomme ved spesialisering (ingen type gitt); den faktiske typen betraktes som en const-peker til char, standardtypen. Hvis det var behov for en annen type ved spesialisering, ville typenavnet bli skrevet i vinkelparentene. Når standardtypen er ønsket ved spesialisering, er det valgfritt å gjenta typen i vinkelparentene, i.e., vinkelbeslagene kan stå tomme.

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

struct

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

mal struct Ages

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

Dette er aldre på studenter i karakter (klasse). Første linje er malerklæringen. Kroppen i seler er selve definisjonen av malen. Aldrene kan sendes ut i hovedfunksjonen () med følgende:

Alder klasse7;
cout << grade7.John << " << grade7.Mary << '\n';

Utgangen er: 11 13. Den første uttalelsen her utfører spesialiseringen. Legg merke til hvordan det er laget. Det gir også et navn på et objekt av strukturen: grad 7. Den andre utsagnet har vanlige strukturobjektuttrykk. En struktur er som en klasse. Her er Ages som et klassenavn, mens grade7 er et objekt for klassen (struct).

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

mal struct Ages

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

En relevant kode for hovedfunksjonen () er som følger:

Alder klasse7;
cout << grade7.John << " << grade7.Peter << '\n';

Utgangen er: 11 12.3. Ved spesialisering må rekkefølgen på typene (argumentene) svare til rekkefølgen på generiske typer i erklæringen.

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

mal struct Ages

T John;
U Peter;
T Mary;
U glede;
;
Alder karakter7 = 11, 12.3, 13, 14.6;

Det første kodesegmentet er kun en erklæring om en mal (det er ingen oppgaver). Det andre kodesegmentet, som bare er en uttalelse, er definisjonen av identifikatoren, grad 7. Venstre side er erklæringen om identifikatoren, grad 7. Høyre side er initialiseringslisten, som tildeler tilsvarende verdier til struct-medlemmene. Det andre segmentet (setning) 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 autotyper. Det er andre ikke-typer, som denne artikkelen ikke tar for seg. En ikke-type er som en ufullstendig type, hvis verdi blir gitt senere og ikke kan endres. Som parameter begynner den med en bestemt ikke-type, etterfulgt av en identifikator. Verdien av identifikatoren blir gitt senere, ved spesialisering, og kan ikke endres igjen (som en konstant, hvis verdi blir gitt senere). Følgende program illustrerer dette:

#inkludere
bruker navneområde std;
mal struct Ages

T John = N;
U Peter = 12.3;
T Mary = N;
U Joy = 14.6;
;
int main ()

Alder klasse7;
cout << grade7.John << " << grade7.Joy << '\n';
retur 0;

Ved spesialisering er den første typen, int, i vinkelparentene det mer for formalitet, for å sikre at antall og rekkefølgen på parametrene tilsvarer antall og rekkefølge av 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 hjelp av den delvise spesialiseringskonstruksjonen, som ikke bruker oppdragsoperatøren. Så, den delvise spesialiseringskonstruksjonen gir standardverdier til en delmengde av generiske typer. Imidlertid er det behov for en basisklasse (struct) og en delvis spesialiseringsklasse (struct) i delspesialiseringsordningen. Følgende program illustrerer dette for en generisk type av to generiske typer:

#inkludere
bruker navneområde std;
// grunnmalsklasse
mal
struct Ages

;
// delvis spesialisering
mal
struct Ages

T1 Johannes = 11;
flyte Peter = 12.3;
T1 Mary = 13;
float Joy = 14.6;
;
int main ()

Alder klasse7;
cout << grade7.John << " << grade7.Joy << '\n';
retur 0;

Identifiser grunnklassedeklarasjonen og dens delvise klassedefinisjon. Malhodedeklarasjonen til baseklassen har alle nødvendige generiske parametere. Malhodeerklæringen til den delvise spesialiseringsklassen har bare generisk type. Det er et ekstra sett med vinkelparenteser som brukes i skjemaet som kommer like etter navnet på klassen i definisjonen av delvis spesialisering. Det er det som faktisk gjør den delvise spesialiseringen. Den har standardtypen og ikke-standardtypen, i rekkefølgen som er skrevet i basisklassen. Merk at standardtypen fremdeles kan gis en annen type i hovedfunksjonen ().

Den relevante koden i hovedfunksjonen () kan være som følger:

Alder klasse7;
cout << grade7.John << " << grade7.Joy << '\n';

Utgangen er: 11 14.6.

Malparameterpakke

En parameterpakke er en malparameter som godtar null eller flere malgeneriske typer for de tilsvarende datatypene. Parameterpakke-parameteren begynner med det reserverte ordet typenavn eller klasse. Dette blir fulgt av tre prikker, og deretter identifikatoren for pakken. Følgende program illustrerer hvordan en malparameterpakke kan brukes med en struktur:

#inkludere
bruker navneområde std;
mal struct Ages

int John = 11;
flyte Peter = 12.3;
int Mary = 13;
float Joy = 14.6;
;
int main ()

Alder klasseB;
cout << gradeB.John << " << gradeB.Mary << '\n';
Alder klasse C;
cout << gradeC.Peter << " << gradeC.Joy << '\n';
Alder klasse D;
cout << gradeD.John << " << gradeD.Joy << '\n';
Alder <> karakterA; // 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å samme måte som funksjonsmaler. Følgende program viser en funksjon med to generiske malparametere og tre argumenter:

#inkludere
bruker navneområde std;
mal void func (T no, U cha, const char * str)

cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main ()

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

Resultatet er som følger:

Det er 12 bøker verdt $ 500 i butikken.

Separasjon fra prototype

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

#inkludere
bruker navneområde std;
mal void func (T no, U cha, const char * str);
mal void func (T no, 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: Funksjonsmalerklæringen kan ikke vises i hovedfunksjonen () eller i noen annen funksjon.

Overbelastning

Overbelastning av samme funksjon kan finne sted med forskjellige malhodeerklæringer. Følgende program illustrerer dette:

#inkludere
bruker navneområde std;
mal void func (T no, U cha, const char * str)

cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

mal void func (T no, 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 verdt $ 500 i butikken.

Det er 12 bøker verdt $ 500 i butikken.

Klassemaler

Funksjonene til malene som er nevnt ovenfor gjelder på samme måte som klassemaler. Følgende program er erklæring, definisjon og bruk av en enkel klasse:

#inkludere
bruker navneområde std;
klasse TheCla

offentlig:
int num;
statisk forkullning;
void func (char cha, const char * str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

statisk tomrom moro (char ch)

hvis (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

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

Resultatet er som følger:

Det er 12 bøker verdt $ 500 i butikken.

Følgende program er programmet ovenfor med en malhodeerklæring:

#inkludere
bruker navneområde 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 moro (U ch)

hvis (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

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

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

Det er 12 bøker verdt $ 500 i butikken.

Separat erklæring

Klassemalledeklarasjonen 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 moro (U ch)

hvis (ch == 'a')
cout << "Official static member function" << '\n';

;

Håndterer statiske medlemmer

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

#inkludere
bruker navneområde 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 moro (U cha)

hvis (ch == 'a')
cout << "Official static member function" << cha << '\n';

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

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

Å tilordne en verdi til et statisk datamedlem er en erklæring og kan ikke være i hovedsak (). Legg merke til bruken og posisjonene til generiske typer og data generiske typer i oppgaveanmeldelsen. I tillegg må du merke at den statiske datamedlemfunksjonen har blitt kalt i hoved (), med de faktiske maldatatypene. Resultatet er følgende:

Offisiell statisk medlemsfunksjon.

Kompilering

Erklæringen (overskrift) 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 hvilken type data som brukes. Enhetene av variabel, funksjon, struktur og klasse kan ha maler som involverer erklæring og definisjon. Å lage en mal innebærer også spesialisering, som er når en generisk type tar en faktisk type. Erklæringen og definisjonen av en mal må begge være i en oversettelsesenhet.

Topp 10 spill å spille på Ubuntu
Windows-plattformen har vært en av de dominerende plattformene for spill på grunn av den enorme andelen spill som utvikles i dag for å støtte Windows ...
5 beste arkadespill for Linux
I dag er datamaskiner seriøse maskiner som brukes til spill. Hvis du ikke kan få den nye høye poengsummen, vil du vite hva jeg mener. I dette innlegge...
Kamp for Wesnoth 1.1. 3.6 Utvikling utgitt
Kamp for Wesnoth 1.1. 3.6 utgitt i forrige måned, er den sjette utgivelsen i 1.1. 3.x-serien, og den leverer en rekke forbedringer, spesielt til bruke...