1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a ° Ciclo Template
2 Template di funzioni I template di funzioni permettono la definizione di funzioni adattabili a diversi tipi di dato. I tipi specifici (predefiniti o definiti dall’utente) per i quali la funzione deve operare vengono definiti al momento dell’invocazione della funzione. Parametri formali Un template di funzione utilizza al posto dei tipi, che saranno definiti solo al momento dell’invocazione, i parametri formali. Un parametro formale rappresenta quindi un tipo che può essere relativo sia agli argomenti, sia al valore restituito e sia alle variabili interne della funzione.
3 Template Dichiarazione di template di funzione Un template di funzione viene dichiarato, assieme a tutti i parametri formali che verranno in esso utilizzati, facendo precedere l’implementazione della funzione con la dichiarazione: template Note: Al posto di class si può utilizzare per la dichiarazione dei parametri formali anche la parola chiave typename. Un template di funzione può ancora subire overloading se nel programma sono presenti altre funzioni che abbiano nome identico, ma argomenti diversi.
4 Template Esempio di template di funzione: template K estrai ( K * punta, int i) { K * loc= punta + i; return *loc;} int main ( ){int arrayInt[5]= {1, 2, 3, 4, 5}; double arrayDouble[5]= {1.1, 2.2, 3.3, 4.4, 5.5}; int s=3; int datoInt= estrai (arrayInt, s); double datoDouble= estrai(arrayDouble, s); cout<<datoInt<<“, “<<datoDouble<<“\n”; return 0;} //Stampa: 4, 4.4
5 Template Template di classe Allo stesso modo dei template di funzione possono essere definiti i template di classe, ossia le classi che possono operare con diversi tipi di dato. Anche in questo caso un template di classe viene dichiarato, assieme a tutti i parametri formali che verranno in esso utilizzati, facendo precedere la definizione della classe con la dichiarazione: template class Nome_Classe {………};
6 Template Funzioni di un template di classe Anche tutte le implementazioni delle funzioni di un template di classe (compreso il costruttore) che utilizzano i parametri formali devono essere precedute dalla dichiarazione di template. Inoltre, sempre per ciascuna funzione, il nome della classe utilizzato per la risoluzione dello scope deve essere seguito dal nome dei parametri formali tra le parentesi. Considerando il caso di un solo parametro formale ogni implementazione di funzione deve essere cioè come segue: template ……. Nome_Classe ::Nome_Funzione (Parametri) { …………………}
7 Template Oggetti di un template di classe L’istanziazione di un oggetto di un template di classe può essere fatto solo dichiarando i tipi specifici che devono sostituire i parametri formali. Per fare ciò al momento dell’istanziazione dell’oggetto, dopo il nome della classe, devono essere elencati tra le parentesi i tipi specifici per i quali viene fatta l’istanziazione. Considerando il caso di un solo parametro formale ogni istanziazione di oggetto deve essere cioè come segue: int main ( ){ ………………….. Nome_Classe Nome_Oggetto (Parametri_Costruttore); ………………………………..}
8 Template Esempio di template di classe: template class Gene { public:Gene ( T ); T getTot ( ); private: T tot;}; // Costruttore template Gene ::Gene (T a){tot= a;} //Funzione membro template T Gene ::getTot ( ) {return tot;}
9 Template Esempio di main che utilizza un template di classe: int main ( ) { Gene datoInt(5); Gene datoDouble(6.66); cout<< datoInt.getTot ( )<<“, “<< datoDouble.getTot ( )<<“\n”; return 0;} Stampa:5, 6.66
10 Template Nota: Nell’implementazione delle funzioni o nel programma main si possono dichiarare puntatori o riferimenti a oggetti di un template di classe senza ancora specificare il tipo da assegnare ai parametri formali. Si possono infatti fare le dichiarazioni del tipo: Nome_Classe …, * Nome_Puntatore, …. Nome_Classe …, & Nome_Riferimento,..
11 Template Parametri non di tipo Nella dichiarazione template possono essere elencati assieme ai parametri formali anche delle variabili di tipo specificato, ossia si possono fare delle dichiarazioni del tipo: template In questo caso il Nome_Variabile può apparire come dato membro nella definizione della classe. Il suo valore attuale viene assegnato al momento dell’istanziazione di un oggetto del template di classe assieme all’assegnazione dei tipi specifici ai parametri formali. La dichiarazione di un oggetto diviene cioè: Nome_Classe Nome_Oggetto (Parametri_Costruttore);
12 Template Ereditarietà dei template Relativamente all’ereditarietà i template si comportano come segue: Da:Si può derivare:Template di classe Classe non di templateTemplate di classe Template di classeClasse non di template Template di classeIstanza di template
13 Template I template e la relazione friend In un template di classe per la classe X dichiarata come segue: template class X {………….}; La dichiarazione:Rende: friend void f1( );f1 friend di ogni istanza del template friend void f2(X &);f2 friend solo della classe X friend void A::f4( );f4 della classe A friend di ogni istanza del template friend void C ::f5(X &); f5 funzione friend della sola classe X friend class y;ogni funzione membro della classe y funzione friend di ogni istanza del template friend class Z ;tutti i membri della istanziazione di Z per un particolare T friend delle istanziazioni di X per lo stesso T
14 Template I template e i membri static Ogni istanza di un template di classe ha la propria copia di ogni dato membro static e tutti gli oggetti della stessa istanza condividono lo stesso dato membro static. I dati membro static devono essere sempre inizializzati con scope a livello di file. Ogni istanza di un template di classe ha la propria copia delle funzioni membro static del template di classe.