templates c with examples
Impara i vari aspetti dei modelli in C ++.
I modelli sono una delle funzionalità più potenti in C ++. I modelli ci forniscono il codice che è indipendente dal tipo di dati.
In altre parole, utilizzando i modelli, possiamo scrivere un codice generico che funziona su qualsiasi tipo di dati. Abbiamo solo bisogno di passare il tipo di dati come parametro. Questo parametro che trasmette il tipo di dati è anche chiamato nome del tipo.
In questo tutorial, esploreremo in dettaglio tutto ciò che riguarda i modelli ei suoi vari aspetti.
=> Fare clic qui per la serie di formazione Absolute C ++.
Cosa imparerai:
- Cosa sono i modelli?
- Come utilizzare modelli / implementazione?
- nome del tipo vs. parola chiave di classe
- Istanziazione e specializzazione dei modelli
- Specializzazione dei modelli
- Modelli variabili C ++
- Conclusione
- Lettura consigliata
Cosa sono i modelli?
Come accennato in precedenza, i modelli sono generici, ovvero indipendenti dal tipo di dati. I modelli vengono utilizzati principalmente per garantire la riusabilità del codice e la flessibilità dei programmi. Possiamo semplicemente creare una semplice funzione o una classe che prende il tipo di dati come parametro e implementare il codice che funziona per qualsiasi tipo di dati.
Per esempio, se vogliamo che un algoritmo di ordinamento funzioni per tutti i tipi di dati numerici così come per le stringhe di caratteri, scriveremo semplicemente una funzione che prende il tipo di dati come argomento e implementa la tecnica di ordinamento.
Quindi, a seconda del tipo di dati (nome del tipo) passato all'algoritmo di ordinamento, possiamo ordinare i dati indipendentemente dal tipo di dati. In questo modo non è necessario scrivere dieci algoritmi per dieci tipi di dati.
Pertanto i modelli possono essere utilizzati nelle applicazioni in cui si richiede che il codice sia utilizzabile per più di un tipo di dati. I modelli vengono utilizzati anche in applicazioni in cui la riusabilità del codice è di primaria importanza.
Come utilizzare modelli / implementazione?
I modelli possono essere implementati in due modi:
- Come modello di funzione
- Come modello di classe
Modello di funzione
Il modello di funzione è proprio come una funzione normale, ma l'unica differenza è che la funzione normale può funzionare solo su un tipo di dati e un codice di modello di funzione può funzionare su più tipi di dati.
Sebbene possiamo effettivamente sovraccaricare una funzione normale per lavorare su vari tipi di dati, i modelli di funzione sono sempre più utili poiché dobbiamo scrivere l'unico programma e può funzionare su tutti i tipi di dati.
Successivamente, vedremo l'implementazione dei modelli di funzione.
La sintassi generale del modello di funzione è:
template T function_name(T args){ …… //function body }
Qui, T è l'argomento del modello che accetta diversi tipi di dati e class è una parola chiave. Invece della classe di parole chiave, possiamo anche scrivere 'nome del tipo'.
Quando un particolare tipo di dati viene passato a function_name, una copia di questa funzione viene eseguita dal compilatore con questo tipo di dati come argomento e la funzione viene eseguita.
Vediamo un esempio per comprendere meglio i modelli di funzione.
#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< Nella funzione main definiamo dati di tipo int, double e char. Chiamiamo la funzione func_swap con ogni tipo di dati. Quindi visualizziamo i dati scambiati per ogni tipo di dati.
Quindi questo mostra che non abbiamo bisogno di scrivere tre funzioni per tre tipi di dati. È sufficiente scrivere una sola funzione e renderla una funzione modello in modo che sia indipendente dal tipo di dati.
Modelli di classe
Come nei modelli di funzione, potremmo avere il requisito di avere una classe simile a tutti gli altri aspetti ma solo a diversi tipi di dati.
In questa situazione, possiamo avere classi diverse per diversi tipi di dati o implementazioni diverse per diversi tipi di dati nella stessa classe. Ma fare questo renderà il nostro codice ingombrante.
La soluzione migliore per questo è usare una classe modello. Anche la classe modello si comporta in modo simile ai modelli di funzione. È necessario passare il tipo di dati come parametro alla classe durante la creazione di oggetti o la chiamata di funzioni membro.
La sintassi generale per il modello di classe è:
template class className{ ….. public: T memVar; T memFunction(T args); };
Nella definizione precedente, T funge da segnaposto per il tipo di dati. Anche memVar e memFunction dei membri pubblici utilizzano T come segnaposto per i tipi di dati.
Una volta definita una classe modello come sopra, possiamo creare oggetti classe come segue:
className classObejct1; className classObject2; className classObject3;
Implementiamo un esempio di codice per dimostrare i modelli di 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 = '< Produzione:
Massimo di 100 e 75 = 100
Massimo di 'A' e 'a' = a
Il programma precedente implementa un esempio di un modello di classe. Abbiamo la classe template myclass. All'interno di questo, abbiamo un costruttore che inizializzerà i due membri a e b della classe. Esiste un'altra funzione membro getMaxval che è anche un modello di funzione che restituisce un massimo di a e b.
Nella funzione main, costruiamo due oggetti, myobject di tipo integer e mychobject di tipo character. Quindi chiamiamo la funzione getMaxval su ciascuno di questi oggetti per determinare il valore massimo.
Si noti che oltre ai parametri del tipo di modello (parametri di tipo T), le funzioni del modello possono anche avere parametri ordinari come funzioni normali e anche valori di parametro predefiniti.
nome del tipo vs. parola chiave di classe
Durante la dichiarazione della classe o della funzione del modello, usiamo una delle due parole chiave class o typename. Queste due parole sono semanticamente equivalenti e possono essere usate in modo intercambiabile.
Ma in alcuni casi, non possiamo usare queste parole come equivalenti. Per esempio, quando usiamo tipi di dati dipendenti in modelli come 'typedef', usiamo typename invece di class.
Inoltre, la parola chiave class deve essere utilizzata quando dobbiamo istanziare esplicitamente un modello.
Istanziazione e specializzazione dei modelli
I modelli sono scritti in modo generico, il che significa che si tratta di un'implementazione generale indipendentemente dal tipo di dati. In base al tipo di dati fornito, dobbiamo generare una classe concreta per ogni tipo di dati.
Per esempio, se abbiamo un algoritmo di ordinamento del modello, possiamo generare una classe concreta per l'ordinamento, un'altra classe per l'ordinamento, ecc. Questa è chiamata istanziazione del modello.
Sostituiamo gli argomenti del modello (tipi di dati effettivi) per i parametri del modello nella definizione della classe del modello.
Per esempio,
template class sort {};
Quando passiamo il tipo di dati, il compilatore sostituisce il tipo di dati con 'T' in modo che l'algoritmo di ordinamento diventi ordinamento.
Ogni volta che utilizziamo una classe o una funzione modello, è necessaria un'istanza quando passiamo un particolare tipo di dati. Se questa istanza non è già presente, il compilatore ne crea una con il particolare tipo di dati. Questa è l'istanza implicita.
Uno svantaggio della creazione di istanze implicite è che il compilatore genera la classe di istanza solo per gli argomenti attualmente utilizzati. Ciò significa che se vogliamo generare una libreria di istanze prima dell'utilizzo di queste istanze, dobbiamo cercare un'istanza esplicita.
Di seguito viene fornito un esempio di dichiarazione del modello:
template class Array(T)
Può essere istanziato esplicitamente come:
template class Array
Quando viene creata un'istanza di una classe, vengono istanziati anche tutti i suoi membri.
Specializzazione dei modelli
Durante la programmazione utilizzando modelli, potremmo trovarci di fronte a una situazione tale da richiedere un'implementazione speciale per un particolare tipo di dati. Quando si verifica una situazione del genere, andiamo per la specializzazione del modello.
Nella specializzazione del modello, implementiamo un comportamento speciale per un particolare tipo di dati oltre alla definizione del modello originale per gli altri tipi di dati.
Per esempio, considera che abbiamo una classe modello ' myIncrement ' che ha un costruttore per inizializzare un valore e una funzione template toIncrement che incrementa il valore di 1.
Questa particolare classe funzionerà perfettamente per tutti i tipi di dati eccetto char. Invece di aumentare il valore di char, perché non dargli un comportamento speciale e convertire invece il carattere in maiuscolo?
Per fare ciò, possiamo optare per la specializzazione del modello per il tipo di dati char.
Questa implementazione è mostrata nell'esempio di codice seguente.
#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: '< Produzione:
Valore int incrementato: 8
Valore maiuscolo: S
Doppio valore incrementato: 12

Nel programma sopra che dimostra la specializzazione del modello, vedi il modo in cui abbiamo dichiarato un modello specializzato per il tipo char. Per prima cosa dichiariamo la classe originale e poi la 'specializziamo' per il tipo char. Per iniziare la specializzazione usiamo un modello vuoto di dichiarazione 'template'.
Quindi, dopo il nome della classe, includiamo il tipo di dati. Dopo queste due modifiche, la classe viene scritta per il tipo char.
come aprire un file jar su Windows 10
Nella funzione principale, notare che non c'è differenza tra l'istanza di tipo char e altri tipi. L'unica differenza è che ridefiniamo la classe specializzata.
Si noti che dobbiamo definire tutti i membri della classe specializzata anche se sono esattamente gli stessi nella classe modello generico / originale. Questo perché non disponiamo di funzionalità di ereditarietà per i membri dal modello generico al modello specializzato.
Modelli variabili C ++
Finora abbiamo visto modelli di funzioni che accettano un numero fisso di argomenti. Esistono anche modelli che accettano un numero variabile di argomenti. Questi modelli di funzione sono chiamati modelli variadici. I modelli Variadic sono una delle funzionalità più recenti di C ++ 11.
I modelli Variadic accettano un numero variabile di argomenti indipendenti dai tipi e gli argomenti vengono risolti in fase di compilazione.
Prendiamo un esempio di programmazione completo per capirlo.
#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'esempio sopra mostra la funzione variadica, 'sommatoria'. Come mostrato sopra, abbiamo prima bisogno di una funzione base che implementi il caso base. Quindi implementiamo la funzione variadica sopra questa funzione.
Nella somma delle funzioni variabili, viene chiamato 'typename ... args' pacchetto parametri modello mentre 'Args ... args' è chiamato pacchetto parametri funzione .
Dopo aver scritto un modello di funzione che implementa il caso base, scriviamo una funzione variadica che implementa il caso generale. La funzione variadica è scritta in modo simile alla ricorsione come mostrato per la sommatoria (args…). Il primo argomento è separato dal pacchetto di parametri della funzione nel tipo T (primo).
Ad ogni chiamata alla somma, l'elenco dei parametri si restringe di un argomento e alla fine viene raggiunta la condizione di base. L'output mostra la somma di interi e caratteri lunghi.
Conclusione
Con questo, concludiamo questo tutorial sui modelli in C ++. I modelli ci aiutano a rendere i nostri programmi generici, ovvero indipendenti dal tipo.
Leggi anche = >> Esercitazione sul modello di boccetta
I programmi generici stanno sempre in cima agli altri programmi poiché non è necessario scrivere programmi separati per ogni tipo di dati. Pertanto lo sviluppo di programmi generici indipendenti dai tipi può essere un passo importante verso una programmazione efficiente.
=> Controlla qui i tutorial di formazione approfonditi su C ++.
Lettura consigliata
- Tutorial sulle funzioni principali di Python con esempi pratici
- Come funziona il test basato sui dati (esempi di QTP e selenio)
- Multithreading in C ++ con esempi
- Tutorial Python DateTime con esempi
- Modello di test case di esempio con esempi di test case (Download)
- Comando Taglia in Unix con esempi
- Modello di esempio per rapporto del test di accettazione con esempi
- Sintassi dei comandi Cat Unix, opzioni con esempi