¿Por qué no puedo hacer esto?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
c++
inheritance
amrhassan
fuente
fuente
Respuestas:
No se puede inicializar
a
yb
enB
porque no son miembros deB
. Son miembros deA
, por lo tanto, soloA
pueden inicializarlos. Puede hacerlos públicos y luego realizar la asignaciónB
, pero esa no es una opción recomendada ya que destruiría la encapsulación. En su lugar, cree un constructorA
para permitirB
(o cualquier subclase deA
) inicializarlos:fuente
a
yb
enB::B()
porque son privadas. No puede inicializarlos porque no son miembros declass B
. Si los hizo públicos o los protegió, podría asignarlos en el cuerpo deB::B()
.a
yb
..." y lo cambié a "No puede inicializar ..." sin asegurarme de que el resto de la oración tuviera sentido. Publicación editada.Dejando de lado el hecho de que son
private
, ya quea
yb
son miembros deA
, están destinados a ser inicializados porA
los constructores de ', no por los constructores de alguna otra clase (derivados o no).Tratar:
fuente
De alguna manera, nadie enumeró la forma más sencilla:
No puede acceder a los miembros base en la lista de inicializadores, pero el propio constructor, al igual que cualquier otro método miembro, puede acceder
public
yprotected
miembros de la clase base.fuente
B
se asigne la instancia de , luego se asignará dentro delB
constructor de. Pero también creo que el compilador aún puede optimizar esto.class A
no podemos confiara
yb
estar inicializados. Cualquier implementación declass C : public A
, por ejemplo, podría olvidarse de llamara=0;
y dejar sina
inicializar.class A { int a = 0;};
), o en el constructor de la clase base. Las subclases aún pueden reinicializarlas en su constructor según sea necesario.Es un ejemplo práctico en caso de que desee inicializar los miembros de datos de la clase Base presentes en el objeto de la clase Derived, mientras que desea enviar estos valores a la interfaz a través de la llamada al constructor de la clase Derived.
fuente
Si bien esto es útil en casos excepcionales (si ese no fuera el caso, el idioma lo habría permitido directamente), eche un vistazo al idioma Base from Member . No es una solución sin código, tendría que agregar una capa adicional de herencia, pero hace el trabajo. Para evitar el código repetitivo, puede usar la implementación de boost
fuente
¿Por qué no puedes hacerlo? Porque el lenguaje no le permite inicializar los miembros de una clase base en la lista de inicializadores de la clase derivada.
¿Cómo puedes hacer esto? Me gusta esto:
fuente
Si no especifica la visibilidad para un miembro de la clase, el valor predeterminado es "privado". Debe hacer que sus miembros sean privados o protegidos si desea acceder a ellos en una subclase.
fuente
Las clases agregadas, como A en su ejemplo (*), deben tener sus miembros públicos y no tener constructores definidos por el usuario. Se inicializan con la lista de inicializadores, por ejemplo,
A a {0,0};
o en su casoB() : A({0,0}){}
. Los miembros de la clase agregada base no se pueden inicializar individualmente en el constructor de la clase derivada.(*) Para ser precisos, como se mencionó correctamente, original
class A
no es un agregado debido a miembros privados no estáticosfuente