Lekcje modułu (2/2)
Szablony Klas
Podobnie jak w przypadku funkcji, klasy również mogą być parametryzowane ze względu na jeden lub więcej typów danych. Pozwala to na definiowanie ogólnych struktur danych (takich jak listy, kolejki, stosy czy wrappery) działających z dowolnym typem danych bez konieczności powielania kodu.
Definiowanie szablonu klasy
Aby zadeklarować szablon klasy, używamy składni template <typename T> bezpośrednio przed definicją klasy. Wewnątrz klasy możemy użyć parametru typu T do definiowania zmiennych składowych, typów zwracanych lub parametrów funkcji składowych.
template <typename T>
class Box {
private:
T value;
public:
Box(T v) : value(v) {}
T getValue() const {
return value;
}
};
Tworzenie instancji (instancjonowanie)
Gdy tworzymy obiekt szablonu klasy, musimy jawnie określić typ w nawiasach ostrych <> (choć od C++17 kompilator może go wydedukować w niektórych kontekstach za pomocą Class Template Argument Deduction lub CTAD):
Box<int> intBox(10); // T staje się int
Box<double> doubleBox(3.14); // T staje się double
Specjalizacja szablonów
Czasami chcemy uzyskać inne zachowanie szablonu klasy, gdy zostanie on zainicjalizowany z określonym typem danych. W takim przypadku definiujemy specjalizację pełną (explicit specialization) za pomocą składni template <>, a następnie definicji klasy, w której określamy typ docelowy:
// Specjalizacja pełna dla typu bool
template <>
class Box<bool> {
private:
bool value;
public:
Box(bool v) : value(v) {}
void printState() {
std::cout << (value ? "Vero" : "Falso");
}
};
Spróbuj sam
Zadeklaruj szablon klasy o nazwie Box, która zawiera prywatną składową o nazwie value typu T, konstruktor inicjalizujący ją oraz publiczną metodę getValue() const zwracającą tę wartość.
Pokaż wskazówkę
Pamiętaj o dodaniu `template <typename T>` przed deklaracją klasy `Box`.
Rozwiązanie dostępne po 3 próbach
Zadeklaruj szablon klasy Wrapper<T> z publiczną składową data typu T, konstruktorem Wrapper(T d) i metodą print() wypisującą data do strumienia std::cout. Następnie utwórz pełną specjalizację dla Wrapper<char>, w której metoda print() wypisuje znak ujęty w pojedyncze cudzysłowy (np. 'A' zamiast A).
Pokaż wskazówkę
Użyj `template <>` do oznaczenia specjalizacji pełnej dla `Wrapper<char>`.
Rozwiązanie dostępne po 3 próbach