templates c with examples
Apreneu els diversos aspectes de les plantilles a C ++.
Les plantilles són una de les funcions més potents de C ++. Les plantilles ens proporcionen el codi que és independent del tipus de dades.
En altres paraules, mitjançant plantilles, podem escriure un codi genèric que funcioni en qualsevol tipus de dades. Només hem de passar el tipus de dades com a paràmetre. Aquest paràmetre que passa el tipus de dades també s'anomena nom de tipus.
En aquest tutorial, explorarem tot sobre les plantilles i els seus diversos aspectes en detall.
=> Feu clic aquí per obtenir la sèrie de formació Absolute C ++.
Què aprendreu:
- Què són les plantilles?
- Com utilitzar plantilles / implementació?
- typename vs. paraula clau de classe
- Instanciació i especialització de plantilles
- Especialització de plantilla
- Plantilles variables C ++
- Conclusió
- Lectura recomanada
Què són les plantilles?
Com s’ha esmentat anteriorment, les plantilles són genèriques, és a dir, independents del tipus de dades. Les plantilles s’utilitzen principalment per garantir la reutilització del codi i la flexibilitat dels programes. Simplement podem crear una funció simple o una classe que prengui el tipus de dades com a paràmetre i implementar el codi que funcioni per a qualsevol tipus de dades.
Per exemple, si volem que funcioni un algorisme d’ordenació per a tots els tipus de dades numèriques i també per a cadenes de caràcters, només escriurem una funció que prengui el tipus de dades com a argument i implementem la tècnica d’ordenació.
Després, segons el tipus de dades (nom del tipus) que es passa a l'algorisme d'ordenació, podem ordenar les dades independentment del tipus de dades. D'aquesta manera no cal escriure deu algoritmes per a deu tipus de dades.
Per tant, les plantilles es poden utilitzar en aplicacions en què necessitem que el codi es pugui utilitzar per a més d'un tipus de dades. Les plantilles també s’utilitzen en aplicacions on la reutilització del codi és de primera importància.
Com utilitzar plantilles / implementació?
Les plantilles es poden implementar de dues maneres:
- Com a plantilla de funció
- Com a plantilla de classe
Plantilla de funció
La plantilla de funcions és com una funció normal, però l’única diferència és que la funció normal només pot funcionar en un tipus de dades i que el codi d’una plantilla de funció pot funcionar en diversos tipus de dades.
Tot i que en realitat podem sobrecarregar una funció normal per treballar en diversos tipus de dades, les plantilles de funcions sempre són més útils ja que hem d’escriure l’únic programa i pot funcionar en tots els tipus de dades.
A continuació, veurem la implementació de plantilles de funcions.
La sintaxi general de la plantilla de funció és:
template T function_name(T args){ …… //function body }
Aquí, T és l’argument de plantilla que accepta diferents tipus de dades i la classe és una paraula clau. En lloc de la classe de paraules clau, també podem escriure 'typename'.
Quan un tipus de dades concret es passa a nom_funció, el compilador fa una còpia d'aquesta funció amb aquest tipus de dades, ja que s'executen un argument i una funció.
Vegem un exemple per entendre millor les plantilles de funcions.
#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< num1 = 20 num2 = 10
d1 = 435,54 d2 = 100,53
ch1 = Z ch2 = A Al programa anterior, hem definit una plantilla de funcions 'func_swap' que intercanvia dos valors. La funció pren dos arguments de referència del tipus T. A continuació, canvia els valors. Com que els arguments són referències, qualsevol canvi que fem als arguments de la funció es reflectirà a la funció de la persona que truca.
A la funció principal, definim dades de tipus int, double i char. Anomenem la funció func_swap amb cada tipus de dades. A continuació, mostrem les dades permeses per a cada tipus de dades.
Per tant, això demostra que no cal escriure tres funcions per a tres tipus de dades. N’hi ha prou d’escriure només una funció i la converteix en una funció de plantilla perquè sigui independent del tipus de dades.
Plantilles de classe
Igual que a les plantilles de funcions, és possible que tinguem el requisit de tenir una classe similar a la resta d’aspectes, però només a tipus de dades diferents.
En aquesta situació, podem tenir classes diferents per a diferents tipus de dades o implementació diferent per a diferents tipus de dades en una mateixa classe. Però fer-ho farà que el nostre codi sigui voluminós.
La millor solució per a això és utilitzar una classe de plantilla. La classe de plantilla també es comporta de manera similar a les plantilles de funcions. Hem de passar el tipus de dades com a paràmetre a la classe mentre es creen objectes o es criden funcions de membre.
La sintaxi general de la plantilla de classe és:
template class className{ ….. public: T memVar; T memFunction(T args); };
A la definició anterior, T actua com a marcador de posició per al tipus de dades. El memVar i memFunction dels membres públics també utilitzen T com a marcador de posició per als tipus de dades.
Una vegada que es defineix una classe de plantilla de la manera anterior, podem crear objectes de classe de la següent manera:
className classObejct1; className classObject2; className classObject3;
Implantem un exemple de codi per demostrar plantilles de classe:
#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 = '< Sortida:
Màxim de 100 i 75 = 100
Màxim de 'A' i 'a' = a
El programa anterior implementa un exemple de plantilla de classe. Tenim la classe de plantilla myclass. Dins d’això, tenim un constructor que inicialitzarà els dos membres a i b de la classe. Hi ha una altra funció membre getMaxval, que també és una plantilla de funció que retorna un màxim de a i b.
A la funció principal, construïm dos objectes, myobject de tipus enter i mychobject de tipus caràcter. A continuació, anomenem la funció getMaxval de cadascun d’aquests objectes per determinar el valor màxim.
Tingueu en compte que, a part dels paràmetres de tipus de plantilla (paràmetres de tipus T), les funcions de plantilla també poden tenir paràmetres ordinaris, com ara funcions normals i també valors de paràmetres predeterminats.
typename vs. paraula clau de classe
En declarar classe o funció de plantilla, fem servir una de les dues paraules clau class o typename. Aquestes dues paraules són semànticament equivalents i es poden utilitzar indistintament.
ado.net preguntes i respostes d’entrevistes per a persones experimentades
Però, en alguns casos, no podem utilitzar aquestes paraules com a equivalents. Per exemple, quan fem servir tipus de dades dependents en plantilles com 'typedef', fem servir typename en lloc de classe.
A més, s’ha d’utilitzar la paraula clau de classe quan hem d’instanciar explícitament una plantilla.
Instanciació i especialització de plantilles
Les plantilles s’escriuen de manera genèrica, cosa que significa que es tracta d’una implementació general independentment del tipus de dades. Segons el tipus de dades proporcionat, hem de generar una classe concreta per a cada tipus de dades.
Per exemple, si tenim un algorisme d'ordenació de plantilla, podem generar una classe concreta per ordenar, una altra classe per ordenar, etc. Això s'anomena instanciació de la plantilla.
Substituïm els arguments de plantilla (tipus de dades reals) pels paràmetres de plantilla a la definició de la classe de plantilla.
Per exemple,
template class sort {};
Quan passem el tipus de dades, el compilador substitueix el tipus de dades per 'T' de manera que l'algorisme d'ordenació es converteix en un tipus.
Cada vegada que fem servir una classe o una funció de plantilla, cal una instància quan passem un tipus de dades concret. Si aquesta instància encara no està present, el compilador en crea una amb el tipus de dades concret. Aquesta és la instanciació implícita.
Un desavantatge de la instanciació implícita és que el compilador genera classe d’instància només per als arguments que s’utilitzen actualment. Això vol dir que si volem generar una biblioteca d’instàncies abans de l’ús d’aquestes instàncies, hem d’anar a la instanciació explícita.
A continuació es mostra un exemple de declaració de plantilla:
template class Array(T)
Es pot instanciar explícitament com:
template class Array
Quan s’instancia una classe, també s’instancien tots els seus membres.
Especialització de plantilla
Mentre programem amb plantilles, ens podríem trobar amb una situació tal que podríem requerir una implementació especial per a un tipus de dades concret. Quan es dóna aquesta situació, optem per l’especialització de plantilles.
A l'especialització de plantilles, implementem un comportament especial per a un tipus de dades concret, a part de la definició de plantilla original per a la resta de tipus de dades.
Per exemple, considerem que tenim una classe de plantilla ' myIncrement ” que té un constructor per inicialitzar un valor i una funció de plantilla aIncrement que augmenta el valor en 1.
Aquesta classe en particular funcionarà perfectament per a tots els tipus de dades, excepte per als caràcters. En lloc d’incrementar el valor del caràcter, per què no donar-li un comportament especial i convertir el caràcter en majúscules?
Per fer-ho, podem optar per l’especialització de plantilles per al tipus de dades char.
Aquesta implementació es mostra a l'exemple de codi següent.
#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: '< Sortida:
Valor int augmentat: 8
Valor en majúscules: S
Doble valor incrementat: 12

Al programa anterior que demostra l'especialització de plantilles, consulteu la forma en què hem declarat una plantilla especialitzada per al tipus de caràcter. Primer declarem la classe original i després la 'especialitzem' per al tipus de caràcter. Per començar l'especialització utilitzem la declaració de plantilla buida 'plantilla'.
Després, després del nom de la classe, incloem el tipus de dades. Després d'aquests dos canvis, la classe s'escriu per al tipus char.
A la funció principal, tingueu en compte que no hi ha diferències entre la instanciació de tipus char i altres tipus. L’única diferència és que redefinim la classe especialitzada.
Tingueu en compte que hem de definir tots els membres de la classe especialitzada tot i que siguin exactament iguals a la classe de plantilla genèrica / original. Això es deu al fet que no tenim cap funció d'herència per als membres, des de la plantilla genèrica fins a la plantilla especialitzada.
Plantilles variables C ++
Fins ara hem vist plantilles de funcions que prenen un nombre fix d'arguments. També hi ha plantilles que tenen un nombre variable d'arguments. Aquestes plantilles de funcions s’anomenen plantilles variadiques. Les plantilles variables són una de les funcions més recents de C ++ 11.
Preguntes i respostes bàsiques per a l'entrevista de suport tècnic
Les plantilles variadiques prenen un nombre variable d'arguments que són segurs per al tipus i els arguments es resolen en temps de compilació.
Prenem un exemple complet de programació per entendre-ho.
#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 = '< L'exemple anterior mostra una funció variadica, 'suma'. Com es mostra més amunt, primer necessitem una funció base que implementi el cas base. A continuació, implementem la funció variadic a la part superior d'aquesta funció.
A la suma de funció variable, es diu 'typename ... args' paquet de paràmetres de plantilla mentre que es diu 'Args ... args' paquet de paràmetres de funció .
Després d’escriure una plantilla de funció que implementa el cas base, escrivim una funció variadica que implementa el cas general. La funció variadica s'escriu de manera similar a la recursió com es mostra per sumar (args ...). El primer argument se separa del paquet de paràmetres de funció al tipus T (primer).
Amb cada crida al sumatori, la llista de paràmetres es redueix mitjançant un argument i, finalment, s’arriba a la condició base. La sortida mostra la suma de caràcters i enters enters.
Conclusió
Amb això, concloguem aquest tutorial sobre plantilles en C ++. Les plantilles ens ajuden a fer que els nostres programes siguin genèrics, és a dir, independents del tipus.
Llegiu també = >> Tutorial de plantilla de matràs
Els programes genèrics sempre se situen per sobre dels altres, ja que no cal escriure programes separats per a cada tipus de dades. Per tant, desenvolupar programes genèrics de tipus segur pot ser un pas important cap a una programació eficient.
=> Consulteu aquí els tutorials de formació en profunditat C ++.
Lectura recomanada
- Tutorial de funcions principals de Python amb exemples pràctics
- Com funcionen les proves impulsades per dades (exemples de QTP i seleni)
- Multithreading en C ++ amb exemples
- Tutorial de Python DateTime amb exemples
- Exemple de plantilla de cas de prova amb exemples de casos de prova (Descarregar)
- Talla l'ordre a Unix amb exemples
- Plantilla de mostra per a l'informe de prova d'acceptació amb exemples
- Sintaxi d'ordres Unix Cat, opcions amb exemples