Uczyniając dziedziczenie prywatnym, zasadniczo mówisz, że nawet fakt, że B dziedziczy po A (w ogóle) jest prywatny - nie jest dostępny / widoczny dla świata zewnętrznego.
Bez wdawania się w długotrwałą dyskusję na temat tego, co by się stało, gdyby było to dozwolone, prosty fakt jest taki, że jest to niedozwolone. Jeśli chcesz użyć wskaźnika do podstawy, aby odwołać się do obiektu typu pochodnego, utkniesz z wykorzystaniem dziedziczenia publicznego.
Prywatne dziedziczenie to nie koniecznie (lub nawet normalnie) przeznaczone do naśladowania zasadę substytucji Liskov . Dziedziczenie publiczne zapewnia, że obiekt pochodny można zastąpić obiektem klasy bazowej, a właściwa semantyka nadal będzie wynikać. Dziedziczenie prywatne jednak tego nie potwierdza. Zwykły opis relacji implikowanej przez dziedziczenie prywatne jest „realizowany w kategoriach”.
Dziedziczenie publiczne oznacza, że klasa pochodna zachowuje wszystkie możliwości klasy bazowej i potencjalnie dodaje więcej. Dziedziczenie prywatne często oznacza mniej więcej coś przeciwnego: klasa pochodna używa ogólnej klasy bazowej do implementacji czegoś z bardziej ograniczonym interfejsem.
Na przykład załóżmy na chwilę, że kontenery w standardowej bibliotece C ++ zostały zaimplementowane przy użyciu dziedziczenia, a nie szablonów. W obecnym systemie std::deque
i std::vector
są kontenerami i std::stack
jest adapterem kontenera, który zapewnia bardziej ograniczony interfejs. Ponieważ jest oparty na szablonach, można go używać std::stack
jako adaptera dla jednego std::deque
lub std::vector
.
Gdybyśmy chcieli zapewnić zasadniczo to samo z dziedziczeniem, prawdopodobnie użylibyśmy dziedziczenia prywatnego, więc std::stack
byłoby coś takiego:
class stack : private vector {
};
W tym przypadku zdecydowanie nie chcemy, aby użytkownik mógł manipulować naszym plikiem stack
tak, jakby był plikiem vector
. Takie postępowanie mogłoby (i prawdopodobnie mogłoby) naruszyć oczekiwania stosu (np. Użytkownik mógłby wstawiać / wyjmować elementy w środku, a nie zgodnie z przeznaczeniem). Zasadniczo używamy vector
jako wygodnego sposobu implementacji naszego stosu, ale jeśli (na przykład) zmieniliśmy implementację na stack
samodzielną (bez zależności od klasy bazowej) lub ponownie zaimplementowaliśmy ją pod względem std::deque
, nie chcemy tego wpływać na dowolny kod klienta - w kodzie klienta ma to być tylko stos, a nie jakaś wyspecjalizowana odmiana wektorów (lub deque).
protected