Introduktion
I grundläggande C ++ programmering, datatyp, t.ex.g., int eller char, måste anges i en deklaration eller en definition. Ett värde som 4 eller 22 eller -5 är ett int. Ett värde som 'A' eller 'b' eller 'c' är ett tecken. Mallmekanismen tillåter programmeraren att använda en generisk typ för en uppsättning faktiska typer. Till exempel kan programmeraren välja att använda identifieraren T för int eller char. Det är möjligt för en C ++ - algoritm att ha mer än en generisk typ. Med, säg, T för int eller char, kan U stå för flyt- eller pekartyp. En klass, som strängen eller vektorklassen, är som en datatyp och de instanserade objekten är som värden för datatypen, vilket är den angivna klassen. Så låter mallmekanismen också programmeraren använda en generisk typidentifierare för en uppsättning klasser.
En C ++ - mall skapar en algoritm oberoende av vilken typ av data som används. Så samma algoritm, med många förekomster av samma typ, kan använda olika typer vid olika körningar. Enheterna av variabel, funktion, struktur och klass kan ha mallar. Den här artikeln förklarar hur man deklarerar mallar, hur man definierar mallar och hur man tillämpar dem i C++. Du bör redan ha kunskap om de ovan nämnda enheterna för att förstå ämnena som omfattas av den här artikeln.
Typer
Skalär
Skalartyperna är ogiltiga, bool, char, int, float och pekare.
Klasser som typer
En viss klass kan betraktas som en typ och dess objekt som möjliga värden.
En generisk typ representerar en uppsättning skalartyper. Listan över skalartyper är omfattande. Int-typen har till exempel andra relaterade typer, såsom kort int, lång int, etc. En generisk typ kan också representera en uppsättning klasser.
Variabel
Ett exempel på en malldeklaration och definition är som följer:
mallT pi = 3.14;
Innan du fortsätter, notera att denna typ av uttalande inte kan visas i huvudfunktionen () eller något blockområde. Den första raden är mallhuvuddeklarationen med det programmerade valda generiska typnamnet T. Nästa rad är definitionen av identifieraren, pi, som är av den generiska typen, T. Precision, oavsett om T är en int eller en flottör eller någon annan typ, kan göras i C ++ main () -funktionen (eller någon annan funktion). Sådan precision kommer att göras med variabeln pi och inte T.
Den första raden är mallhuvuddeklarationen. Denna deklaration börjar med det reserverade ordet, mallen och sedan de öppna och slutna vinkelparenteserna. Inom vinkelfästena finns det minst en generisk typidentifierare, såsom T, ovan. Det kan finnas mer än en generisk typidentifierare, var och en föregås av det reserverade ordet, typnamn. Sådana generiska typer i den positionen kallas mallparametrar.
Följande uttalande kan skrivas i huvud () eller i någon annan funktion:
cout << piOch funktionen skulle visa 3.14. Uttrycket pi
Vid specialisering placeras den valda datatypen, som float, i vinkelparenteser efter variabeln. Om det finns mer än en mallparameter i mallhuvuddeklarationen kommer det att finnas ett motsvarande antal datatyper i samma ordning i specialiseringsuttrycket.
Vid specialisering är en typ känd som ett mallargument. Blanda inte mellan detta och funktionsargumentet för funktionsanrop.
Standardtyp
Om ingen typ anges vid specialisering antas standardtypen. Så från följande uttryck:
mallU pi = "kärlek";
displayen från:
cout << pi<> << '\n';
är "kärlek" för den ständiga pekaren till röding. Notera i deklarationen att U = const char *. Vinkelfästena är tomma vid specialisering (ingen typ anges); den faktiska typen anses vara en const-pekare till char, standardtypen. Om någon annan typ behövdes vid specialisering, skulle typnamnet skrivas i vinkelparenteserna. När standardtyp önskas vid specialisering är det valfritt att upprepa typen i vinkelfästena, dvs.e., vinkelfästena kan lämnas tomma.
Obs: standardtypen kan ändras vid specialisering genom att ha en annan typ.
struct
Följande exempel visar hur en mallparameter kan användas med en struct:
mallT John = 11;
T Peter = 12;
T Mary = 13;
T Joy = 14;
;
Dessa är åldrar av studenter i en klass (klass). Den första raden är malldeklarationen. Kroppen i hängslen är den faktiska definitionen av mallen. Åldrarna kan anges i huvudfunktionen () med följande:
Åldrarcout << grade7.John << " << grade7.Mary << '\n';
Utgången är: 11 13. Det första uttalandet här utför specialiseringen. Lägg märke till hur det har gjorts. Det ger också ett namn för ett objekt av strukturen: grad7. Det andra uttalandet har vanliga strukturobjektuttryck. En struktur är som en klass. Här är åldrar som ett klassnamn, medan grad 7 är ett objekt i klassen (struct).
Om vissa åldrar är heltal och andra är flytande, behöver strukturen två generiska parametrar enligt följande:
mallT John = 11;
U Peter = 12.3;
T Mary = 13;
U Joy = 14.6;
;
En relevant kod för huvudfunktionen () är som följer:
Åldrarcout << grade7.John << " << grade7.Peter << '\n';
Utgången är: 11 12.3. Vid specialisering måste typordningen (argumenten) motsvara ordningen på de generiska typerna i deklarationen.
Malldeklarationen kan skiljas från definitionen enligt följande:
mallT John;
U Peter;
T Mary;
U Joy;
;
Åldrar
Det första kodsegmentet är enbart en malldeklaration (det finns inga tilldelningar). Det andra kodsegmentet, som bara är ett uttalande, är definitionen av identifieraren, grad 7. Den vänstra sidan är deklarationen för identifieraren, grad 7. Den högra sidan är initialiserarlistan som tilldelar motsvarande värden till struct-medlemmarna. Det andra segmentet (uttalande) kan skrivas i huvudfunktionen (), medan det första segmentet förblir utanför huvudfunktionen ().
Icke-typ
Exempel på icke-datatyper inkluderar int, pekare till objekt, pekare att fungera och autotyper. Det finns andra icke-typer som denna artikel inte behandlar. En icke-typ är som en ofullständig typ vars värde ges senare och inte kan ändras. Som en parameter börjar den med en viss icke-typ, följt av en identifierare. Värdet på identifieraren ges senare vid specialisering och kan inte ändras igen (som en konstant vars värde ges senare). Följande program illustrerar detta:
#omfattaanvänder namnrymd std;
mall
T John = N;
U Peter = 12.3;
T Mary = N;
U Joy = 14.6;
;
int main ()
Åldrar
cout << grade7.John << " << grade7.Joy << '\n';
returnera 0;
Vid specialisering är den första typen, int, i vinkelparenteserna mer för formalitet, för att se till att antalet och ordningen på parametrarna motsvarar antalet och ordningen på typerna (argument). Värdet av N har givits vid specialisering. Utgången är: 11 14.6.
Delvis specialisering
Låt oss anta att en mall har fyra generiska typer och att det bland de fyra typerna finns behov av två standardtyper. Detta kan uppnås med hjälp av den partiella specialiseringskonstruktionen, som inte använder uppdragsoperatören. Så, den partiella specialiseringskonstruktionen ger standardvärden till en delmängd av generiska typer. I det partiella specialiseringsschemat behövs dock en basklass (struct) och en partiell specialiseringsklass (struct). Följande program illustrerar detta för en generisk typ av två generiska typer:
#omfattaanvänder namnrymd std;
// basmallklass
mall
struct Åldrar
;
// delvis specialisering
mall
struct Åldrar
T1 John = 11;
flyta Peter = 12.3;
T1 Mary = 13;
float Joy = 14.6;
;
int main ()
Åldrar
cout << grade7.John << " << grade7.Joy << '\n';
returnera 0;
Identifiera basklassdeklarationen och dess partiella klassdefinition. Mallklassdeklarationen för basklassen har alla nödvändiga generiska parametrar. Malldeklarationen för den partiella specialiseringsklassen har endast den generiska typen. Det finns en extra uppsättning vinkelfästen som används i schemat som kommer strax efter klassens namn i definitionen av partiell specialisering. Det är det som faktiskt gör den partiella specialiseringen. Den har standardtyp och icke-standardtyp, i den ordning som skrivs i basklassen. Observera att standardtypen fortfarande kan ges en annan typ i huvudfunktionen ().
Den relevanta koden i huvudfunktionen () kan vara följande:
Åldrarcout << grade7.John << " << grade7.Joy << '\n';
Utgången är: 11 14.6.
Mallparameterpaket
Ett parameterpaket är en mallparameter som accepterar noll eller flera mallgeneriska typer för motsvarande datatyper. Parameterpaketparametern börjar med det reserverade ordet typnamn eller klass. Detta följs av tre punkter och sedan identifieraren för paketet. Följande program illustrerar hur ett mallparameterpaket kan användas med en struktur:
#omfattaanvänder namnrymd std;
mall
int John = 11;
flyta Peter = 12.3;
int Mary = 13;
float Joy = 14.6;
;
int main ()
Åldrar
cout << gradeB.John << " << gradeB.Mary << '\n';
Åldrar
cout << gradeC.Peter << " << gradeC.Joy << '\n';
Åldrar
cout << gradeD.John << " << gradeD.Joy << '\n';
Åldrar <> klass A; // som standard
cout << gradeA.John << " << gradeA.Joy << '\n';
returnera 0;
Utgången är:
11 1312.3 14.6
11 14.6
11 14.6
Funktionsmallar
Mallfunktionerna som nämns ovan gäller på samma sätt som funktionsmallar. Följande program visar en funktion med två generiska mallparametrar och tre argument:
#omfattaanvänder namnrymd std;
mall
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';
int main ()
funk (12, '$', "500");
returnera 0;
Utgången är som följer:
Det finns 12 böcker värda $ 500 i butiken.
Separation från prototyp
Funktionsdefinitionen kan separeras från sin prototyp, som följande program visar:
#omfattaanvänder namnrymd std;
mall
mall
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';
int main ()
funk (12, '$', "500");
returnera 0;
Obs! Funktionsmalldeklarationen kan inte visas i huvudfunktionen () eller i någon annan funktion.
Överbelastning
Överbelastning av samma funktion kan ske med olika mallhuvuddeklarationer. Följande program illustrerar detta:
#omfattaanvänder namnrymd std;
mall
cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';
mall
cout << "There are " << no << " books worth $" << str << " in the store." << '\n';
int main ()
funk (12, '$', "500");
funk (12, "500");
returnera 0;
Utgången är:
Det finns 12 böcker värda $ 500 i butiken.
Det finns 12 böcker värda $ 500 i butiken.
Klassmallar
Funktionerna i mallarna som nämns ovan gäller på samma sätt som klassmallar. Följande program är deklarationen, definitionen och användningen av en enkel klass:
#omfattaanvänder namnrymd std;
klass 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 tomrumskul (char ch)
om (ch == 'a')
cout << "Official static member function" << '\n';
;
int main ()
TheCla invände;
obj.num = 12;
obj.funk ('$', "500");
returnera 0;
Utgången är som följer:
Det finns 12 böcker värda $ 500 i butiken.
Följande program är ovanstående program med en mall-huvuddeklaration:
#omfattaanvänder namnrymd std;
mall
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 tomrumskul (U ch)
om (ch == 'a')
cout << "Official static member function" << '\n';
;
int main ()
TheCla
obj.num = 12;
obj.funk ('$', "500");
returnera 0;
I stället för ordet typnamn i mallparameterlistan kan ordklassen användas. Observera specialiseringen i deklarationen av objektet. Utgången är fortfarande densamma:
Det finns 12 böcker värda $ 500 i butiken.
Separat deklaration
Klassmalldeklarationen kan separeras från klasskoden enligt följande:
mallmall
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 tomrumskul (U ch)
om (ch == 'a')
cout << "Official static member function" << '\n';
;
Att hantera statiska medlemmar
Följande program visar hur du får åtkomst till en statisk datamedlem och en statisk medlemsfunktion:
#omfattaanvänder namnrymd std;
mall
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 tomrumskul (U cha)
om (ch == 'a')
cout << "Official static member function" << cha << '\n';
;
mall
int main ()
TheCla
returnera 0;
Tilldela ett värde till en statisk datamedlem är en deklaration och kan inte vara i huvudsak (). Notera användningen och positionerna för de generiska typerna och den generiska datatypen i tilldelningsuttalandet. Observera dessutom att den statiska datamedelfunktionen har anropats i huvudsak () med de faktiska malldatatyperna. Resultatet är följande:
Officiell statisk medlemsfunktion.
Sammanställning
Deklarationen (rubriken) och definitionen av en mall måste vara i en fil. Det vill säga de måste vara i samma översättningsenhet.
Slutsats
C ++ - mallar gör en algoritm oberoende av vilken typ av data som används. Enheterna av variabel, funktion, struktur och klass kan ha mallar som involverar deklaration och definition. Att skapa en mall innebär också specialisering, det vill säga när en generisk typ tar en faktisk typ. Deklarationen och definitionen av en mall måste båda vara i en översättningsenhet.