c++ - qué - Acceder a miembros protegidos en una clase derivada
qué hereda una clase hijo de una clase padre (6)
Ayer me encontré con un error y, aunque es fácil de entender, quería asegurarme de entender bien C ++.
Tengo una clase base con un miembro protegido:
class Base
{
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
Esto compila y funciona bien. Ahora extiendo Base pero aún quiero usar b:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
Tenga en cuenta que en este caso DoSomething
sigue tomando una referencia a una Base
, no Derived
. Esperaría que todavía pueda tener acceso a that.b
dentro de Derived
, pero obtengo un error al cannot access protected member
(MSVC 8.0 - aún no he probado gcc).
Obviamente, agregar un getter público en b
resolvió el problema, pero me preguntaba por qué no podía tener acceso directamente a b
. Pensé que cuando utilizas la herencia pública, las variables protegidas siguen siendo visibles para la clase derivada.
Como se mencionó, es solo la forma en que funciona el lenguaje.
Otra solución es explotar la herencia y pasar al método principal:
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
Base::DoSomething(that);
d=0;
}
};
Se puede acceder a los miembros protected
:
- a través de
this
puntero - o al mismo tipo de miembros protegidos, incluso si se declara en la base
- o de clases de amigos, funciones
Para resolver su caso, puede usar una de las dos últimas opciones.
Aceptar derivado en Derived :: DoSomething o declarar Derived friend
to Base:
class Derived;
class Base
{
friend class Derived;
protected:
int b;
public:
void DoSomething(const Base& that)
{
b+=that.b;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
b+=that.b;
d=0;
}
};
También puede considerar getters públicos en algunos casos.
Solo puede acceder a miembros protegidos en instancias de su tipo (o derivados de su tipo).
No puede acceder a los miembros protegidos de una instancia de tipo padre o primo.
En su caso, la clase Derived
solo puede acceder al miembro b
de una instancia Derived
, no a una instancia Base
diferente.
Cambiar el constructor para tomar una instancia Derived
también resolverá el problema.
Tiene acceso a los miembros protegidos de Derived
, pero no a los de Base
(incluso si la única razón por la que es un miembro protegido de Derived
es porque se hereda de Base
)
Use this
puntero para acceder a los miembros protegidos
class Derived : public Base
{
protected:
int d;
public:
void DoSomething(const Base& that)
{
this->b+=that.b;
d=0;
}
};
class Derived : public Base
{
protected:
int d;
public:
void DoSomething()
{
b+=this->b;
d=0;
}
};
//this will work