2010-07-14 25 views
41

Ayer encontré un error y, aunque es fácil de recorrer, quería asegurarme de entender C++ correctamente.Acceso a miembros protegidos en una clase derivada

que tienen 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 muy bien. Ahora extiende la base, pero aún desea utilizar b:

class Derived : public Base 
{ 
    protected: 
    int d; 
    public: 
    void DoSomething(const Base& that) 
    { 
     b+=that.b; 
     d=0; 
    } 
}; 

Nótese que en este caso DoSomething se sigue tomando una referencia a un Base, no Derived. Esperaría que todavía puedo tener acceso a that.b dentro de Derived, pero me sale un error de 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 al b. Pensé que cuando utilizas la herencia pública, las variables protegidas siguen siendo visibles para la clase derivada.

+2

Consulte http://www.gotw.ca/gotw/076.htm (Nota: no use eso en el código de producción). – Brian

Respuesta

29

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 primario o primo.

En su caso, la clase Derived sólo se puede acceder al miembro de b de una instancia Derived, no de un Base instancia diferente.

Cambiar el constructor para tomar una instancia Derived también resolverá el problema.

+0

¿Quiere decir aquí que podemos acceder a los miembros protegidos desde nuestros propios objetos, no desde los objetos de la clase base? Si es así, ¿por qué es así? –

+1

@AnishaKaul: solo puede acceder a los miembros protegidos de su clase base en una instancia de su tipo, no un tipo de primo. Por ejemplo, 'Button' no puede acceder a una propiedad protegida desde' Control' en un 'TextBox'. – SLaks

+1

'Solo puede acceder a los miembros protegidos de su clase base en una instancia de su tipo, no en un tipo de primo". Ha escrito nuevamente la misma declaración que escribió anteriormente. Por favor, eche un vistazo aquí: http: //stackoverflow.com/questions/9139824/how-to-access-protected-members-in-a-derived-class –

3

Usted tiene acceso a los miembros protected de Derived, pero no los de Base (incluso si la única razón por la que es un miembro protegido de Derived es porque ha heredado de Base)

+1

Esto no funciona. Considera "Tienes acceso a los miembros' privados' de 'Derived'." y las implicaciones para los miembros 'privados' heredados de 'Base'. –

2

Como se ha mencionado, es sólo la forma en que el el lenguaje funciona.

Otra solución consiste en explotar la herencia y pasar al método parent:

class Derived : public Base 
{ 
    protected: 
    int d; 
    public: 
    void DoSomething(const Base& that) 
    { 
     Base::DoSomething(that); 
     d=0; 
    } 
}; 
+1

He dado un mal ejemplo en la pregunta, pero no puedo llamar a Base :: DoSomething porque DoSomething en realidad se trata de hacer las cosas de manera diferente cuando se trata de una derivada en lugar de una base. – miked

-3

Uso 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; 
    } 
}; 
+1

Esta respuesta es incorrecta. La clase derivada no puede acceder a "b" de la clase base ya que está declarada como protegida (esto es lo que el usuario preguntó en primer lugar). Este código generará un error de compilación. – tantuni

+1

Qué falta de respuesta. Es el 'b' de' ese' ese es el problema. Y agregar 'this->' no solo no está relacionado sino que también es una completa no operación porque está implícito si se omite. Deseo que las personas conozcan un poco sobre un idioma y prueben cualquier código que escriban antes de publicarlo como respuesta. –

0

protected miembros se puede acceder a:

  • a this puntero
  • o para los mismos miembros protegidos tipo, incluso si se declara en la base
  • o de las clases amigo, funciones

para resolver su caso, puede utilizar una de las últimas dos opciones.

Acepta derivados en Derivado :: HacerAlgo o declarar Derivado friend a 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 captadores públicas en algunos casos.

Cuestiones relacionadas