Dziedziczenie pojedyncze i wielokrotne
Modeluj relacje is-a za pomocą dziedziczenia pojedynczego i unikaj pułapek dziedziczenia wielokrotnego
Dziedziczenie pojedyncze i wielokrotne to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 1 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.
Czym jest dziedziczenie?
Dziedziczenie pozwala jednej klasie, czyli klasie pochodnej, ponownie wykorzystać inną klasę, czyli klasę bazową, i ją rozszerzyć. Modeluje relacje typu „jest”.
class Animal {
public:
void breathe() { std::cout << "breathing\n"; }
};
class Dog : public Animal {
public:
void bark() { std::cout << "Woof!\n"; }
};Dziedziczenie publiczne
Należy użyć public, aby modelować relację „jest” — pies jest zwierzęciem. Składowe zachowują swój poziom dostępu w klasie pochodnej.
Dziedziczenie chronione i prywatne
Dziedziczenie protected i private modeluje relację „jest zaimplementowane za pomocą” i jest rzadko używane. W takich przypadkach należy preferować kompozycję.
Dostęp do składowych klasy bazowej
Klasa pochodna może bezpośrednio korzystać z dowolnej publicznej lub chronionej składowej klasy bazowej.
Dog d;
d.breathe(); // inherited from Animal
d.bark(); // own memberKolejność wywoływania konstruktorów
Konstruktory klasy bazowej są uruchamiane przed konstruktorami klasy pochodnej. Należy używać listy inicjalizatorów składowych, aby przekazywać argumenty do klasy bazowej.
class Pet : public Animal {
std::string name_;
public:
Pet(std::string n) : Animal(), name_(std::move(n)) {}
};Kolejność wywoływania destruktorów
Destruktory są uruchamiane w odwrotnej kolejności — najpierw destruktor klasy pochodnej, a następnie bazowej. Jeśli obiekt jest usuwany za pomocą wskaźnika do klasy bazowej, destruktor klasy bazowej powinien być oznaczony jako virtual.
Wielokrotne dziedziczenie
C++ pozwala klasie dziedziczyć po więcej niż jednej klasie bazowej. Należy korzystać z tej możliwości oszczędnie, ponieważ komplikuje projekt.
class Printable { public: virtual void print() = 0; };
class Serializable { public: virtual std::string serialize() = 0; };
class Document : public Printable, public Serializable {
// implements both interfaces
};Problem diamentu
Jeśli dwie klasy bazowe mają wspólną klasę bazową, klasa pochodna otrzymuje dwie kopie tej klasy bazowej. Problem ten można rozwiązać za pomocą dziedziczenia wirtualnego.
class A {};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {}; // D has ONE A, not twoKoszt dziedziczenia wirtualnego
Wirtualne klasy bazowe wprowadzają narzut — dodatkowy wskaźnik w każdym obiekcie oraz dodatkowe pośrednie odwołanie przy każdym dostępie do składowej klasy bazowej. Należy ich unikać, gdy jest to możliwe.
Kompozycja a dziedziczenie
Często kompozycja typu „ma” jest prostsza niż dziedziczenie typu „jest”. Obiekt Car ma obiekt Engine — nie należy dziedziczyć po Engine w klasie Car.
class Engine { /* ... */ };
class Car {
Engine engine_; // composition
};Dziedziczenie interfejsu a dziedziczenie implementacji
Dwa typowe zastosowania:
- Interfejs — dziedziczenie po klasie bazowej zawierającej wyłącznie funkcje wirtualne w celu spełnienia kontraktu
- Implementacja — dziedziczenie w celu ponownego użycia kodu (CRTP, mixiny)
Kiedy stosować dziedziczenie
Dziedziczenie należy stosować, gdy:
- istnieje rzeczywista relacja typu „jest”
- potrzebny jest polimorfizm w czasie wykonywania za pomocą funkcji wirtualnych
- klasa bazowa została zaprojektowana z myślą o dziedziczeniu
Szybki test
Jaka technika zapobiega powstaniu dwóch kopii wspólnej klasy bazowej przy użyciu wielokrotnego dziedziczenia?
Podsumowanie
Dziedziczenie publiczne modeluje relacje typu „jest”. Wielokrotne dziedziczenie jest dozwolone, ale problem diamentu wymaga dziedziczenia wirtualnego. W relacjach typu „ma” oraz w celu ponownego użycia kodu należy preferować kompozycję.
Często zadawane pytania
Czy lekcja „Dziedziczenie pojedyncze i wielokrotne” jest bezpłatna?
Tak — pełny tekst „Dziedziczenie pojedyncze i wielokrotne” 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 „Dziedziczenie pojedyncze i wielokrotne”?
Modeluj relacje is-a za pomocą dziedziczenia pojedynczego i unikaj pułapek dziedziczenia wielokrotnego Ć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 1 z 4.
Ile czasu zajmuje lekcja „Dziedziczenie pojedyncze i wielokrotne”?
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
- Dziedziczenie pojedyncze i wielokrotne
- Funkcje wirtualne i vtable
- Klasy abstrakcyjne i czysto wirtualne metody
- Dziedziczenie a kompozycja — kompromisy