Lezioni del modulo (2/2)
Classi Template
Come per le funzioni, anche le classi possono essere parametrizzate rispetto a uno o più tipi di dato. Questo ci consente di definire strutture dati generiche (come liste, code, pile o wrapper) che funzionano con qualsiasi tipo di dato senza dover duplicare il codice.
Definizione di una Classe Template
Per dichiarare una classe template, usiamo la sintassi template <typename T> immediatamente prima della definizione della classe. All'interno della classe, possiamo usare il parametro di tipo T per definire variabili membro, tipi di ritorno o parametri di funzioni membro.
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() const {
return value;
}
};
Istanziazione
Quando creiamo un oggetto di una classe template, dobbiamo specificare esplicitamente il tipo tra parentesi angolari <> (sebbene a partire da C++17 il compilatore possa dedurlo in alcuni contesti tramite Class Template Argument Deduction o CTAD):
Box<int> intBox(10); // T diventa int
Box<double> doubleBox(3.14); // T diventa double
Specializzazione dei Template
A volte desideriamo un comportamento differente per una classe template quando viene istanziata con un tipo specifico. In questo caso, definiamo una specializzazione totale usando la sintassi template <> seguita dalla definizione della classe in cui specifichiamo il tipo target:
// Specializzazione totale per il tipo bool
template <>
class Box<bool> {
private:
bool value;
public:
Box(bool v) : value(v) {}
void printState() {
std::cout << (value ? "Vero" : "Falso");
}
};
Prova tu
Dichiara una classe template chiamata Box che contiene un membro privato chiamato value di tipo T, un costruttore che lo inizializza e un metodo pubblico getValue() const che restituisce il valore.
Mostra suggerimento
Ricorda di anteporre `template <typename T>` alla dichiarazione della classe `Box`.
Soluzione disponibile dopo 3 tentativi
Dichiara una classe template Wrapper<T> con un membro pubblico data di tipo T, un costruttore Wrapper(T d) e un metodo print() che stampa data su std::cout. Successivamente, crea una specializzazione totale per Wrapper<char> in cui il metodo print() stampa il carattere racchiuso tra singoli apici (es. 'A' invece di A).
Mostra suggerimento
Usa `template <>` per indicare la specializzazione totale di `Wrapper<char>`.
Soluzione disponibile dopo 3 tentativi