• Lunes 29 de Abril de 2024, 08:24

Autor Tema:  Herencia [c++]  (Leído 1575 veces)

AnioN

  • Miembro MUY activo
  • ***
  • Mensajes: 339
    • Ver Perfil
Herencia [c++]
« en: Sábado 9 de Junio de 2007, 14:52 »
0
Hola, tengo una duda con respecto a la herencia privada y protegida.

Citar
Herencia publica (class Derivada: public Base ) : Con este tipo de herencia se respetan los comportamientos originales de las visibilidades de la clase Base en la clase Derivada.
Herencia privada (clase Derivada: private Base) : Con este tipo de herencia todo componente de la clase Base, será privado en la clase Derivada (ojo! siempre será privado aunque ese dato fuese público en la clase Base)
Herencia protegida (clase Derivada: protected Base) : Con este tipo de herencia, todo componente publico y protegido de la clase Base, será protegido en la clase Derivada, y los componentes privados, siguen siendo privados.

Por ej en la herencia privada, todos los miembros pasan a ser privados en la clase derivada, esto que quiere decir?, en que casos se utiliza este tipo de herencia?

Lo que es herencia publica, creo que lo entiendo bien. Lo interpreto asi, corrijanme si estoy equivocado.

Código: Text
  1. class base {
  2.   private:
  3.     int a;
  4.   protected:
  5.     int b;
  6.   public:
  7.     int c;
  8. };
  9.  
  10. class derivada: public base {
  11.   private:
  12.      ...
  13.   protected:
  14.     ...
  15.   public:
  16.     ...
  17. };
  18.  

Lo que entiendo es que desde la clase derivada puedo acceder en forma directa a lo que es "c" y "b", pero en forma indirecta a "a", con forma directa me refiero a que puedo hacer "c = 3;" desde la derivada, y con forma indirecta me refiero a que desde la derivada la unica forma de acceder a un miembro privado es a traves de una funcion (publica o protegida) de la clase base.

daltomi

  • Nuevo Miembro
  • *
  • Mensajes: 19
    • Ver Perfil
Re: Herencia [c++]
« Respuesta #1 en: Sábado 9 de Junio de 2007, 16:02 »
0
¿Quién encapsula más la herencia?¿protected o private? El orden de estos operadores es asi: Public(tibio), Protected(caliente), Private(muy caliente), muchos confunden estos operadores.
No hay que confundir el alcance de estos operadores. Si uno observa bien, verá que estos operadores se utilizan dentro de la clase y fuera.
Dentro, me refiero cuando hacemos:
Código: Text
  1.  
  2. class base:
  3. public:
  4. int publ;
  5. .....
  6.  
  7.  
Y fuera, me refiero cuando hacemos:
Código: Text
  1.  
  2. class deriv: private base
  3. {
  4. ........
  5.  
  6.  
¿Por que? Las leyes que hay que cumplir en el primer ejemplo es dentro de la derivada y en el segundo ejemplo es cuando se define una variable como clase.
Código: Text
  1.  
  2. deriv d;
  3.  
  4.  
Se entiende no?
Bien. Hice un ejemplo que espero que sirva para entender un poco mejor. Este ejemplo no se lee :huh: , sino que se compila cambiando los operadores en "deriv:'operador' base" y recién se lee lo que dice el compi. :rolleyes:
Les doy una ayuda colocando los signos de comentarios en las líneas inválidas, para no pasarse toda la tarde compilando  :hola:
Código: Text
  1.  
  2.  
  3. class base
  4. {
  5. private:
  6.   int bas_priv;
  7. protected:
  8.   int bas_proc;
  9. public:
  10.   int bas_publ;
  11.  
  12. };
  13.  
  14.  
  15. class deriv : private base
  16. {
  17. private:
  18.   int dev_priv;
  19. protected:
  20.   int dev_proc;
  21. public:
  22.   int dev_publ;
  23.   deriv(int);
  24. };
  25.  
  26. /*Constructor*/
  27. /*¿aqui importa si 'deriv: private | public | protected base' ????*/
  28. deriv::deriv(int i)
  29. {
  30.   dev_priv = i;
  31.   dev_proc = i;
  32.   dev_publ = i;
  33.  
  34. //  bas_priv = i;//error sin acceso x interno de base.
  35.   bas_proc = i;
  36.   bas_publ = i;
  37. }
  38.  
  39. int main(int argc, char* argv[])
  40. {
  41.   deriv d(22);
  42. //  d.dev_priv = 0;//error sin acceso x interno de deriv.
  43. //  d.dev_proc = 0;//error sin acceso x interno de deriv.
  44.   d.dev_publ = 0;
  45.  
  46. //  d.bas_priv = 0;//error sin acceso x interno a base.
  47. //  d.bas_proc = 0;//error sin acceso x interno a base.
  48. //  d.bas_publ = 0;//error sin acceso x ?.
  49.   return(0);
  50. }
  51.  
  52.  
Vayan probando cambiando el operador en "deriv: 'operador' base" y luego quiten algunos comentarios y verán que lo dicho anteriormente se cumple. ¿Cuando se puede quitar el comentario de esta línea?:
Código: Text
  1.  
  2. //  d.bas_publ = 0;//error sin acceso x interno a base.
  3.  
  4.  

Saludos.

AnioN

  • Miembro MUY activo
  • ***
  • Mensajes: 339
    • Ver Perfil
Re: Herencia [c++]
« Respuesta #2 en: Domingo 10 de Junio de 2007, 00:48 »
0
todavia no me termina de cerrar el tema. O sea, si la herencia es publica, protegida o privada desde la derivada voy a poder acceder en forma directa a los miembros publicos y protegidos. Solo los privados son inaccesibles en forma directa.

Lo que noto es que fuera de la clase derivada, dentro del main, solo puedo acceder en forma directa a los miembros publicos si y solo si la herencia es publica, pero si esta es privada o protegida no es posible.
A lo que me refiero es a lo siguiente, estos codigos son similares.
Código: Text
  1.  
  2. class base
  3. {
  4. private:
  5.  int bas_priv;
  6. protected:
  7.  int bas_proc;
  8. public:
  9.  int bas_publ;
  10. };
  11.  
  12. class deriv : public base
  13. {
  14. private:
  15.  int dev_priv;
  16. protected:
  17.  int dev_proc;
  18. public:
  19.  int dev_publ;
  20.  deriv(int);
  21. };
  22.  
  23. deriv::deriv(int i)
  24. {
  25.  dev_priv = i;
  26.  dev_proc = i;
  27.  dev_publ = i;
  28.  
  29.  bas_priv = i;//no puedo acceder
  30.  bas_proc = i;
  31.  bas_publ = i;
  32. }
  33.  
  34.  

Código: Text
  1.  
  2. class base
  3. {
  4. private:
  5.  int bas_priv;
  6. protected:
  7.  int bas_proc;
  8. public:
  9.  int bas_publ;
  10. };
  11.  
  12. class deriv : protected base
  13. {
  14. private:
  15.  int dev_priv;
  16. protected:
  17.  int dev_proc;
  18. public:
  19.  int dev_publ;
  20.  deriv(int);
  21. };
  22.  
  23. deriv::deriv(int i)
  24. {
  25.  dev_priv = i;
  26.  dev_proc = i;
  27.  dev_publ = i;
  28.  
  29.  bas_priv = i;//no puedo acceder
  30.  bas_proc = i;
  31.  bas_publ = i;
  32. }
  33.  
  34.  

Código: Text
  1.  
  2. class base
  3. {
  4. private:
  5.  int bas_priv;
  6. protected:
  7.  int bas_proc;
  8. public:
  9.  int bas_publ;
  10. };
  11.  
  12. class deriv : private base
  13. {
  14. private:
  15.  int dev_priv;
  16. protected:
  17.  int dev_proc;
  18. public:
  19.  int dev_publ;
  20.  deriv(int);
  21. };
  22.  
  23. deriv::deriv(int i)
  24. {
  25.  dev_priv = i;
  26.  dev_proc = i;
  27.  dev_publ = i;
  28.  
  29.  bas_priv = i;//no puedo acceder
  30.  bas_proc = i;
  31.  bas_publ = i;
  32. }
  33.  
  34.  

O sea, desde la definicion de las clases el acceso a los miembros no cambia aunque cambie el tipo de herencia(public, protected, private). Nunca voy a poder acceder a un miembro privado de una clase base, pero a los demas miembros si.

daltomi

  • Nuevo Miembro
  • *
  • Mensajes: 19
    • Ver Perfil
Re: Herencia [c++]
« Respuesta #3 en: Domingo 10 de Junio de 2007, 06:05 »
0
:) ok, todo perfecto,pero....
Cita de: ""AnioN""
O sea, desde la definicion de las clases el acceso a los miembros no cambia aunque cambie el tipo de herencia(public, protected, private

Si, pero recordá lo que dije, las leyes que hay que cumplir para el tipo de herencia es cuando se declara una variable tipo clase, en nuestro caso dentro del main(), tal como dijiste:
Cita de: ""AnioN""
Lo que noto es que fuera de la clase derivada, dentro del main, solo puedo acceder en forma directa a los miembros publicos si y solo si la herencia es publica, pero si esta es privada o protegida no es posible.

 :unsure: ¿Entonces para que instanciar una clase base como protected o private, si sólo como public se puede acceder? Bien, que secederia si le das a un compañero el código de clases que tenemos y hace asi:
Código: Text
  1.  
  2. deriv d;
  3. base b;
  4.  
  5.  
Y empieza a hacer malabares con las clases y los datos,digamos que podrian tener datos sensibles y se dispersan o modifican sin ningún orden(todo esto según la fucionalidad de las clases). Ahi es donde entra en juego protected y private a la hora de la herencia de clase:
 :D Un ejemplo para entender esto es el código siguiente, que utiliza sobrecarga de funciones para el ejemplo.
Código: Text
  1.  
  2.  
  3. class base{
  4.  
  5. public:
  6.   void func(double);
  7.  
  8. protected:
  9.   void func(long);
  10.  
  11. private:
  12.   void func(int);
  13.  
  14. };
  15.  
  16.  
  17.  
  18. class deriv : public base
  19. {
  20.  
  21. public:
  22. //Constructor, llama a base::func(long).ok es protected.
  23.   deriv(  )   { func(42L); }
  24.  
  25.   void f(  ) { func(42); }//Error: base::func(int) es privado.
  26. };
  27.  
  28.  
  29.  
  30. class global : private deriv
  31. {
  32.  
  33. public:
  34. // Constructor. llama  a deriv::f( ).ok es publico.
  35. // pero existe un error en deriv::f( ).
  36.   global() { f(  ); }
  37.  
  38. };
  39.  
  40.  
  41. int main(int argc, char* argv[])
  42. {
  43.   deriv d;
  44.  
  45.   d.func(42L);//Error: func(long) es accesible desde base o deriv solamente.
  46.             //Aunque base esta instanciado public en deriv, base::func(long) es protected.
  47.  
  48.   d.func(42);//Error. peor todavia. base::func(int) es privado.
  49.  
  50.   global g;
  51.   g.f( );//Error. ya que si bien deriv::f( ) es publico no se puede acceder
  52.     // desde aqui por que deriv está instanciado privado en global.
  53.  
  54.   return(0);
  55. }
  56.  
  57.  
Saludos.

AnioN

  • Miembro MUY activo
  • ***
  • Mensajes: 339
    • Ver Perfil
Re: Herencia [c++]
« Respuesta #4 en: Domingo 10 de Junio de 2007, 13:53 »
0
Citar
¿Entonces para que instanciar una clase base como protected o private, si sólo como public se puede acceder? Bien, que secederia si le das a un compañero el código de clases que tenemos y hace asi:
como instanciar una clase base como protected o private?, te referis a una clase derivada ahi?

Sigo sin entender la diferencia de la herencia privada y protegida.  :(


Estuve haciendo un par de pruebas y llegue a la siguiente conclusion, quisiera saber si es acertada o no.

El tema del tipo de herencia si es privada, publica, o protegida entra en juego recien cuando es una herencia jerarquica, o sea si tengo 3 clases y se heredan jerarquicamente, es a partir de ahi. Si tengo solo 2 clases y no va a haber mas herencia no hay diferencia alguna. Por ej este codigo.


Las lineas que estan comentadas son las que no permiten compilar segun el tipo de herencia.

Herencia Publica
Código: Text
  1. #include <iostream>
  2.  
  3. class base {
  4.   private:
  5.     int base_priv;
  6.   public:
  7.     int base_pub;
  8.  
  9.     base() {
  10.  
  11.  
  12.     }
  13.   protected:
  14.     int base_prot;
  15. };
  16.  
  17.  
  18. class derivada: public base {
  19.   private:
  20.     int deriv_priv;
  21.   public:
  22.     int deriv_pub;
  23.  
  24.     derivada() {
  25.       deriv_priv = 1;
  26.       deriv_pub = 2;
  27.       deriv_prot = 3;
  28.       //base_priv = 4;
  29.       base_pub = 5;
  30.       base_prot = 6;
  31.     }
  32.   protected:
  33.     int deriv_prot;
  34. };
  35.  
  36.  
  37. class derivada2: public derivada {
  38.   private:
  39.     int deriv2_priv;
  40.   public:
  41.     int deriv2_pub;
  42.  
  43.     derivada2() {
  44.       //deriv_priv = 1;
  45.       deriv_pub = 2;
  46.       deriv_prot = 3;
  47.       //base_priv = 4;
  48.       base_pub = 5;
  49.       base_prot = 6;
  50.     }
  51.   protected:
  52.     int deriv2_prot;
  53. };
  54.  
  55.  
  56. int main()
  57. {
  58.   std::cout << "Hello world!" << std::endl;
  59.   return 0;
  60. }
  61.  

Herencia Protegida
Código: Text
  1. #include <iostream>
  2.  
  3. class base {
  4.   private:
  5.     int base_priv;
  6.   public:
  7.     int base_pub;
  8.  
  9.     base() {
  10.  
  11.  
  12.     }
  13.   protected:
  14.     int base_prot;
  15. };
  16.  
  17.  
  18. class derivada: protected base {
  19.   private:
  20.     int deriv_priv;
  21.   public:
  22.     int deriv_pub;
  23.  
  24.     derivada() {
  25.       deriv_priv = 1;
  26.       deriv_pub = 2;
  27.       deriv_prot = 3;
  28.       //base_priv = 4;
  29.       base_pub = 5;
  30.       base_prot = 6;
  31.     }
  32.   protected:
  33.     int deriv_prot;
  34. };
  35.  
  36.  
  37. class derivada2: public derivada {
  38.   private:
  39.     int deriv2_priv;
  40.   public:
  41.     int deriv2_pub;
  42.  
  43.     derivada2() {
  44.       //deriv_priv = 1;
  45.       deriv_pub = 2;
  46.       deriv_prot = 3;
  47.       //base_priv = 4;
  48.       base_pub = 5;
  49.       base_prot = 6;
  50.     }
  51.   protected:
  52.     int deriv2_prot;
  53. };
  54.  
  55.  
  56. int main()
  57. {
  58.   std::cout << "Hello world!" << std::endl;
  59.   return 0;
  60. }
  61.  

Herencia Privada
Código: Text
  1. #include <iostream>
  2.  
  3. class base {
  4.   private:
  5.     int base_priv;
  6.   public:
  7.     int base_pub;
  8.  
  9.     base() {
  10.  
  11.  
  12.     }
  13.   protected:
  14.     int base_prot;
  15. };
  16.  
  17.  
  18. class derivada: private base {
  19.   private:
  20.     int deriv_priv;
  21.   public:
  22.     int deriv_pub;
  23.  
  24.     derivada() {
  25.       deriv_priv = 1;
  26.       deriv_pub = 2;
  27.       deriv_prot = 3;
  28.       //base_priv = 4;
  29.       base_pub = 5;
  30.       base_prot = 6;
  31.     }
  32.   protected:
  33.     int deriv_prot;
  34. };
  35.  
  36.  
  37. class derivada2: public derivada {
  38.   private:
  39.     int deriv2_priv;
  40.   public:
  41.     int deriv2_pub;
  42.  
  43.     derivada2() {
  44.       //deriv_priv = 1;
  45.       deriv_pub = 2;
  46.       deriv_prot = 3;
  47.       //base_priv = 4;
  48.       //base_pub = 5;
  49.       //base_prot = 6;
  50.     }
  51.   protected:
  52.     int deriv2_prot;
  53. };
  54.  
  55.  
  56. int main()
  57. {
  58.   std::cout << "Hello world!" << std::endl;
  59.   return 0;
  60. }
  61.  

La diferencia que encontre es que con la herencia privada no puedo acceder en forma directa a los miembros de la clase base desde derivada2. Pero tanto la publica, como protegida no encontre diferencia.