La necesidad de la palabra clave public
es solo eso para las clases definidas con la palabra clave class
, el modificador de acceso predeterminado (para todo - miembros de datos, funciones de miembro y clases base) es private
. Así
class World : State {};
es lo mismo que:
class World : private State {};
y que probablemente no es lo que quiere - que significa que la clase base sólo es accesible dentro de la clase World
. Los forasteros "no saben" que la herencia está allí en absoluto.
Para las clases definidas con la palabra clave struct
, el modificador de acceso por defecto es public
, por lo que podía escritura:
struct World : State {};
y conseguir algo que tanto se ve y se comporta un poco como cualquier otro idioma con la herencia. Pero la palabra clave struct
, y el hecho de que define una clase, realmente solo existe para compatibilidad con C.No encontrará muchas guías de estilo en C++ que recomienden usarlo solo para obtener la accesibilidad pública predeterminada: generalmente se usa solo para clases que son POD, o tal vez solo para clases sin funciones miembro.
En cuanto a por qué C++ tiene herencia privada en primer lugar: para la mayoría de los propósitos, la herencia privada es una forma de composición. composición normal:
class World {
State state;
public:
void foo() {
state.bar();
state.baz();
and so on
}
};
Es decir, el mundo sabe que la clase se implementa usando un Estado, y el mundo exterior no sabe cómo se implementa Mundial.
vs
class World : private State {
public:
void foo() {
bar();
baz();
and so on
}
};
Es decir, el Mundial de la clase sabe que es implementado por ser un Estado, y el mundo exterior no sabe cómo se implementa. Pero puede exponer selectivamente partes de la interfaz de estado, por ejemplo, poniendo using State::bar;
en la parte pública de la definición de Mundo. El efecto es como si hubiera escrito laboriosamente una función (o varias sobrecargas) en World, cada una de las cuales delega a la misma función en State.
Además de evitar el tipeo, un uso común de la herencia privada es cuando la clase State
está vacía, es decir, no tiene miembros de datos. Entonces, si es miembro de World
debe ocupar un espacio (es cierto que, dependiendo del diseño del objeto, este podría ser un espacio que de lo contrario sería relleno, por lo que no aumenta necesariamente el tamaño de World
), pero si es una clase base entonces se activa una cosa llamada "optimización de clase base vacía", y puede ser de tamaño cero. Si está creando un lote de objetos, esto podría importar. La herencia privada permite la optimización, pero el mundo exterior no deducirá una relación "is-a", porque no ve la herencia.
Es una gran diferencia: si tiene dudas, simplemente use la composición explícita. La introducción de la herencia para guardar la escritura está muy bien hasta que tenga alguna consecuencia inesperada.
¿Quiso escribir 'clase World: private State {}'? En lo que realmente escribiste, la herencia es pública. –
Quizás quiso decir 'class World: private State'? – detunized
@Steve, @detunized Lo siento por mi estúpido error. Modifiqué la pregunta. – Eonil