0Pricing
C++ Academy · Lekcja

Funkcje wirtualne i vtable

Implementuj polimorfizm czasu wykonywania za pomocą funkcji wirtualnych i poznaj pojęcie vtable

Funkcje wirtualne i vtable to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.

Wiązanie statyczne a dynamiczne

Domyślnie wywołania składowych są wiązane statycznie — kompilator wybiera funkcję na podstawie zadeklarowanego typu. W przypadku funkcji virtual wywołanie jest wiązane dynamicznie na podstawie rzeczywistego typu.

Deklarowanie funkcji wirtualnej

Funkcję w klasie bazowej należy oznaczyć jako virtual. Klasy pochodne mogą ją przesłaniać.

class Shape {
public:
    virtual double area() const = 0;        // pure virtual
    virtual ~Shape() = default;
};

class Circle : public Shape {
    double r_;
public:
    Circle(double r) : r_(r) {}
    double area() const override { return 3.14159 * r_ * r_; }
};

Specyfikator override

Do metod klas pochodnych należy dodać override. Kompilator sprawdzi, czy funkcja rzeczywiście przesłania funkcję wirtualną, dzięki czemu wykryje literówki w sygnaturze.

Specyfikator final

final uniemożliwia dalsze przesłanianie. Należy go używać w przypadku klas, po których nie powinno się dziedziczyć, lub metod, których nie powinno się już przesłaniać.

class Concrete final : public Base { /* ... */ };
class Base {
    virtual void f() final;   // cannot be overridden
};

Wywoływanie za pomocą wskaźnika do klasy bazowej

Na tym polega istota polimorfizmu: wskaźnik do klasy bazowej może wywołać właściwą metodę klasy pochodnej.

Shape* s = new Circle(3.0);
std::cout << s->area();   // 28.27... (Circle::area)
delete s;

Pojęcie vtable

Każda klasa polimorficzna ma ukrytą tablicę vtable — tablicę wskaźników do funkcji. Każdy obiekt przechowuje ukryty wskaźnik (vptr) do tablicy vtable swojej klasy.

Koszt wywołań wirtualnych

Wywołanie wirtualne wymaga jednego dodatkowego odwołania pośredniego przez vtable. W większości kodu jest to pomijalny koszt. Należy unikać takich wywołań w pętlach wewnętrznych, jeśli pomiary wykażą, że stanowią wąskie gardło.

Czysto wirtualne funkcje

Dołącz = 0, aby uczynić funkcję czysto wirtualną. Klasy pochodne muszą ją przesłonić, aby można było tworzyć ich obiekty. Klasa staje się abstrakcyjna.

Wirtualne destruktory

Jeśli klasa ma dowolną funkcję wirtualną lub ma być usuwana za pomocą wskaźnika do klasy bazowej, należy wyposażyć ją w wirtualny destruktor. W przeciwnym razie destruktor klasy pochodnej nie zostanie uruchomiony.

class Base {
public:
    virtual ~Base() = default;   // safe to delete through Base*
};

Polimorfizm z inteligentnymi wskaźnikami

Obiekty polimorficzne należy przechowywać za pomocą inteligentnych wskaźników do klasy bazowej. Inteligentny wskaźnik prawidłowo obsłuży ich niszczenie.

std::unique_ptr<Shape> s = std::make_unique<Circle>(3.0);

Ponownie o obcinaniu

Przekazanie obiektu klasy pochodnej przez wartość do funkcji oczekującej klasy bazowej powoduje obcięcie części pochodnej. W przypadku parametrów polimorficznych należy używać referencji lub wskaźników.

Kompromis wydajnościowy

Funkcje wirtualne zapewniają elastyczność za cenę niewielkiego narzutu w czasie wykonywania. Szablony oferują polimorfizm w czasie kompilacji bez kosztu w czasie wykonywania — wybór zależy od tego, czy polimorfizm jest potrzebny podczas działania programu.

Szybki test

Dlaczego polimorficzna klasa bazowa powinna mieć destruktor virtual?

Podsumowanie

Funkcje wirtualne umożliwiają polimorfizm w czasie wykonywania za pomocą osobnej tablicy vtable dla każdej klasy. Przesłonięcia należy oznaczać jako override, a dalsze dziedziczenie blokować za pomocą final. Polimorficzne klasy bazowe zawsze powinny mieć wirtualny destruktor.

Często zadawane pytania

Czy lekcja „Funkcje wirtualne i vtable” jest bezpłatna?

Tak — pełny tekst „Funkcje wirtualne i vtable” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Funkcje wirtualne i vtable”?

Implementuj polimorfizm czasu wykonywania za pomocą funkcji wirtualnych i poznaj pojęcie vtable Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C++ Academy?

Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Funkcje wirtualne i vtable”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?

Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dziedziczenie pojedyncze i wielokrotne
  2. Funkcje wirtualne i vtable
  3. Klasy abstrakcyjne i czysto wirtualne metody
  4. Dziedziczenie a kompozycja — kompromisy
← Powrót do C++ Academy