c++ - resueltos - miembros de una clase en programacion orientada a objetos
¿Cómo puedo inicializar las variables miembro de la clase base en el constructor de clase derivado? (7)
¿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)
{
}
};
¿Por qué no puedo hacer esto?
class A
{
public:
int a, b;
};
class B : public A
{
B() : A(), a(0), b(0)
{
}
};
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 los constructores de A, no por otros constructores de 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) {}
}
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 tu caso B() : A({0,0}){}
. Los miembros de la clase de agregado base no pueden inicializarse individualmente en el constructor de la clase derivada.
(*) Para ser precisos, como se mencionó correctamente, la class A
original no es un agregado debido a miembros privados no estáticos
No puede inicializar b
en B
porque no son miembros de B
Son miembros de A
, por lo tanto, solo A
puede inicializarlos. Puede hacer que sean públicos, luego hacer la asignación en B
, pero esa no es una opción recomendada ya que destruiría la encapsulación. En su lugar, cree un constructor en A
para permitir que B
(o cualquier subclase de A
) los inicialice:
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.
{
}
};
Si bien esto es útil en casos excepcionales (si ese no fuera el caso, el lenguaje lo hubiera permitido directamente), eche un vistazo a la base del idioma del miembro . 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, podrías usar la implementación de boost
Si no especifica la visibilidad para un miembro de la clase, su valor predeterminado es "privado". Debe hacer que sus miembros sean privados o protegidos si desea acceder a ellos en una subclase.
# 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 de trabajo en caso de que desee inicializar los miembros de datos de la clase Base presentes en el objeto de la clase Derivada, mientras que desea insertar estos valores en la interfaz a través de la llamada del constructor de la clase Derivada.