¿Por qué no puedo hacer esto?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
¿Por qué no puedo hacer esto?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
Respuestas:
No se puede inicializar a
y b
en B
porque no son miembros de B
. Son miembros de A
, por lo tanto, solo A
pueden inicializarlos. Puede hacerlos públicos y luego realizar la asignación B
, pero esa no es una opción recomendada ya que destruiría la encapsulación. En su lugar, cree un constructor A
para permitir B
(o cualquier subclase de A
) inicializarlos:
class A
{
protected:
A(int a, int b) : a(a), b(b) {} // Accessible to derived classes
// Change "protected" to "public" to allow others to instantiate A.
private:
int a, b; // Keep these variables private in A
};
class B : public A
{
public:
B() : A(0, 0) // Calls A's constructor, initializing a and b in A to 0.
{
}
};
a
y b
en B::B()
porque son privadas. No puede inicializarlos porque no son miembros de class B
. Si los hizo públicos o los protegió, podría asignarlos en el cuerpo de B::B()
.
a
y b
..." 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 que a
y b
son miembros de A
, están destinados a ser inicializados por A
los constructores de ', no por los constructores de alguna otra clase (derivados o no).
Tratar:
class A
{
int a, b;
protected: // or public:
A(int a, int b): a(a), b(b) {}
};
class B : public A
{
B() : A(0, 0) {}
};
De alguna manera, nadie enumeró la forma más sencilla:
class A
{
public:
int a, b;
};
class B : public A
{
B()
{
a = 0;
b = 0;
}
};
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
y protected
miembros de la clase base.
B
se asigne la instancia de , luego se asignará dentro del B
constructor de. Pero también creo que el compilador aún puede optimizar esto.
class A
no podemos confiar a
y b
estar inicializados. Cualquier implementación de class C : public A
, por ejemplo, podría olvidarse de llamar a=0;
y dejar sin a
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.
# include<stdio.h>
# include<iostream>
# include<conio.h>
using namespace std;
class Base{
public:
Base(int i, float f, double d): i(i), f(f), d(d)
{
}
virtual void Show()=0;
protected:
int i;
float f;
double d;
};
class Derived: public Base{
public:
Derived(int i, float f, double d): Base( i, f, d)
{
}
void Show()
{
cout<< "int i = "<<i<<endl<<"float f = "<<f<<endl <<"double d = "<<d<<endl;
}
};
int main(){
Base * b = new Derived(10, 1.2, 3.89);
b->Show();
return 0;
}
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.
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
¿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:
class A
{
public:
A(int a, int b) : a_(a), b_(b) {};
int a_, b_;
};
class B : public A
{
public:
B() : A(0,0)
{
}
};
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.
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 caso B() : 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áticos