Lekcje modułu (2/2)
Polimorfizm i funkcje wirtualne
Polimorfizm (polymorphism) pozwala na traktowanie obiektów różnych klas pochodnych za pomocą wskaźnika lub referencji do ich klasy bazowej, co gwarantuje wykonanie odpowiedniej wersji danej metody w czasie wykonywania programu (późne wiązanie / Late Binding).
Funkcje wirtualne: virtual i override
Aby włączyć polimorfizm dla metody, musimy ją zadeklarować ze słowem kluczowym virtual wewnątrz klasy bazowej. W klasach pochodnych używamy specyfikatora override, aby wyraźnie zaznaczyć, że nadpisujemy tę metodę.
class Employee {
public:
virtual void work() {
std::cout << "Lavoro generico" << std::endl;
}
// WAŻNE: Wirtualny destruktor w klasie bazowej w celu uniknięcia wycieków pamięci
virtual ~Employee() = default;
};
class Developer : public Employee {
public:
void work() override {
std::cout << "Scrittura codice in C++" << std::endl;
}
};
Używając wskaźników do klasy bazowej, C++ wywoła odpowiednią metodę w czasie wykonywania programu:
Employee* emp = new Developer();
emp->work(); // Stampa "Scrittura codice in C++" invece di "Lavoro generico"
delete emp;
Klasy abstrakcyjne i czyste funkcje wirtualne
Czysta funkcja wirtualna (pure virtual function) to wirtualna funkcja składowa zadeklarowana z = 0 na końcu. Reprezentuje ona formalny kontrakt: klasa bazowa nie dostarcza żadnej implementacji, delegując ją w całości do podklas.
Klasa zawierająca przynajmniej jedną czystą funkcję wirtualną nazywana jest klasą abstrakcyjną i nie można utworzyć jej instancji bezpośrednio.
class Instrument {
public:
virtual void play() = 0; // Virtuale pura
virtual ~Instrument() = default;
};
class Piano : public Instrument {
public:
void play() override {
std::cout << "Suono del pianoforte..." << std::endl;
}
};
Spróbuj sam
Zdefiniuj metodę wirtualną makeSound() w Animal wypisującą 'Some sound'. Następnie nadpisz ją w klasie Cat przy użyciu specyfikatora override, aby wypisywała 'Meow'.
Pokaż wskazówkę
Pamiętaj o dodaniu `virtual` przed metodą w klasie bazowej i umieszczeniu `override` po nawiasach parametrów w klasie pochodnej.
Rozwiązanie dostępne po 3 próbach
Zadeklaruj czystą funkcję wirtualną print() zwracającą void w klasie abstrakcyjnej Printable. Utwórz następnie klasę Document dziedziczącą public po Printable i zaimplementuj metodę print(), aby wypisywała 'Printing Document'.
Pokaż wskazówkę
Czystą funkcję wirtualną deklaruje się za pomocą sygnatury `virtual void print() = 0;`. Upewnij się, że `Document` dziedziczy public po `Printable`.
Rozwiązanie dostępne po 3 próbach