Al hacer que la herencia sea privada, básicamente estás diciendo que incluso el hecho de que B herede de A (en absoluto) es privado, no accesible / visible para el mundo exterior.
Sin entrar en una larga discusión sobre lo que sucedería si estuviera permitido, el simple hecho es que no está permitido. Si desea usar un puntero a la base para referirse a un objeto de tipo derivado, entonces está bastante atrapado con el uso de herencia pública.
La herencia privada no necesariamente (ni siquiera normalmente) pretende seguir el principio de sustitución de Liskov . La herencia pública afirma que un objeto derivado se puede sustituir por un objeto de la clase base, y la semántica adecuada seguirá resultando. Sin embargo, la herencia privada no lo afirma. La descripción habitual de la relación implícita en la herencia privada es "se implementa en términos de".
La herencia pública significa que una clase derivada mantiene todas las capacidades de la clase base y potencialmente agrega más. La herencia privada a menudo significa más o menos lo contrario: que la clase derivada usa una clase base general para implementar algo con una interfaz más restringida.
Por ejemplo, supongamos por el momento que los contenedores de la biblioteca estándar de C ++ se implementaron usando herencia en lugar de plantillas. En el sistema actual, std::deque
y std::vector
son contenedores, y std::stack
es un adaptador de contenedor que proporciona una interfaz más restringida. Dado que se basa en plantillas, puede utilizarlo std::stack
como adaptador para std::deque
o std::vector
.
Si quisiéramos proporcionar esencialmente lo mismo con la herencia, probablemente usaríamos herencia privada, por std::stack
lo que sería algo como:
class stack : private vector {
};
En este caso, definitivamente no queremos que el usuario pueda manipular nuestro stack
como si fuera un vector
. Hacerlo podría (y probablemente lo haría) violar las expectativas de una pila (por ejemplo, el usuario podría insertar / eliminar elementos en el medio, en lugar de una forma puramente similar a una pila como se pretendía). Básicamente, lo estamos usando vector
como una forma conveniente de implementar nuestra pila, pero si (por ejemplo) cambiamos la implementación para que sea stack
independiente (sin dependencia de una clase base) o la reimplementamos en términos de std::deque
, no queremos eso para afectar cualquier código de cliente: para el código de cliente, se supone que esto es solo una pila, no una variedad especializada de vector (o deque).
protected