• Martes 12 de Noviembre de 2024, 20:44

Autor Tema:  Problema de novato con clases  (Leído 4535 veces)

JuaNiYoT

  • Nuevo Miembro
  • *
  • Mensajes: 15
    • Ver Perfil
Problema de novato con clases
« en: Miércoles 13 de Abril de 2011, 02:13 »
0
Hola, estoy aprendiendo ahora c++ y para programar estoy usando eclipse, ahora bien, cuando defino una clase, uso una opción que trae de generar código fuente para que genere los get y set para la clase. El problema es que he dado con una clase en la que he metido un tipo enum y no me hace automáticamente los get y set, y he probado a hacerlos yo pero me da fallo. Si alguien me puede ayudar... aqui le dejo el fragmento de código. Gracias y un saludo.

Código: C++
  1. /* EN CLIENTE.H */
  2.  
  3. class Cliente{
  4. private:
  5.     string DNI; /**<DNI sin letra*/
  6.     string nombre; /**<Nombre separado por un espacio en blanco si es necesario*/
  7.     unsigned int edad;
  8.     enum estado_civil{soltero, casado, viudo, divorciado};
  9. public:
  10.     string getDNI() const;
  11.     unsigned int getEdad() const;
  12.     string getNombre() const;
  13.     enum getEstado_civil() const;
  14.  /*error en esta linea - Multiple markers at this line
  15.     - Syntax error
  16.     - use of enum 'getEstado_civil' without previous
  17.      declaration
  18.     - expected unqualified-id before ')' token*/
  19.  
  20.     void setDNI(string DNI);
  21.     void setEdad(unsigned int edad);
  22.     void setNombre(string nombre);
  23.     void setEstado_civil(enum estado_civil);
  24. };
  25.  

Código: C++
  1. /*EN CLIENTE.CPP*/
  2.  
  3. string Cliente::getDNI() const
  4. {
  5.     return DNI;
  6. }
  7.  
  8. unsigned int Cliente::getEdad() const
  9. {
  10.     return edad;
  11. }
  12.  
  13. string Cliente::getNombre() const
  14. {
  15.     return nombre;
  16. }
  17.  
  18.  
  19. /*ERROR AQUI - - Syntax error
  20.     - expected unqualified-id before ')' token
  21.     - 'getEstado_civil' in class 'Cliente' does not
  22.      name a type*/
  23. enum Cliente::getEstado_civil() const
  24. {
  25.     return estado_civil;
  26. }
  27.  
  28. void Cliente::setDNI(string DNI)
  29. {
  30.     this->DNI = DNI;
  31. }
  32.  
  33. void Cliente::setEdad(unsigned int edad)
  34. {
  35.     this->edad = edad;
  36. }
  37.  
  38. void Cliente::setNombre(string nombre)
  39. {
  40.     this->nombre = nombre;
  41. }
  42.  
  43. void Cliente::setEstado_civil(enum estado_civil)
  44. {
  45.     this->estado_civil = estado_civil;
  46. /*ERROR
  47. - expected primary-expression before
  48.      ';' token
  49.     - invalid use of 'enum
  50.      Cliente::estado_civil'*/
  51. }
  52.  
  53.  

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #1 en: Miércoles 13 de Abril de 2011, 04:20 »
0
El error esta en que estas usando mal el enum, enum funciona como si crearas un nuevo tipo, no como si crearas una variable, cuando defines enum estado_civil{soltero, casado, viudo, divorciado}, estas creando un nuevo tipo llamado estado_civil, este tipo solo podra tomar los valores soltero, casado, viudo, divorciado, que internamente valdran 0, 1, 2, 3.

Ademas, necesitas una variable interna a tu clase de tipo privado, que guarde el valor del estado civil, y no, no se puede llamar estado_civil, ya que ese es el nombre del nuevo tipo, tiene que tener un nombre diferente, y debe ser de tipo estado_civil.

Entonces debes definir los metodos getEstado_civil() y setEstado_civil() de manera que utilicen el nuevo tipo, y la variable interna que guarda el estado civil.

No se si me explique bien, pero te dejo el codigo de como deberia ser, supongo que con eso comprenderas mejor lo que te explique arriba. Ademas, he definido estado_civil de tipo public en lugar de private, para que puedas acceder al nuevo tipo fuera de la clase, que pienso que seria mas correcto.

Código: C++
  1.  
  2. /* EN CLIENTE.H */
  3. class Cliente {
  4. public:
  5.     // enum funciona como si definieras un nuevo tipo
  6.     enum estado_civil{soltero, casado, viudo, divorciado};
  7.     string getDNI() const;
  8.     unsigned int getEdad() const;
  9.     string getNombre() const;
  10.  
  11.     // Defines el metodo como si regresa un valor de tipo estado_civil
  12.     estado_civil getEstado_civil() const;
  13.  
  14.     void setDNI(string DNI);
  15.     void setEdad(unsigned int edad);
  16.     void setNombre(string nombre);
  17.  
  18.     // Defines el metodo como si le pasas un parametro de tipo estado_civil
  19.     void setEstado_civil(estado_civil civil);
  20.  
  21. private:
  22.     string DNI; /**<DNI sin letra*/
  23.     string nombre; /**<Nombre separado por un espacio en blanco si es necesario*/
  24.     unsigned int edad;
  25.  
  26.     // Variable interna (privada) de tipo estado_civil para guardar el estado civil
  27.     estado_civil civil;
  28. };
  29.  
  30.  

Código: C++
  1.  
  2. /*EN CLIENTE.CPP*/
  3. string Cliente::getDNI() const
  4. {
  5.     return DNI;
  6. }
  7.  
  8. unsigned int Cliente::getEdad() const
  9. {
  10.     return edad;
  11. }
  12.  
  13. string Cliente::getNombre() const
  14. {
  15.     return nombre;
  16. }
  17.  
  18. // Defines el metodo como si regresa un valor de tipo estado_civil
  19. Cliente::estado_civil Cliente::getEstado_civil() const
  20. {
  21.     return this->civil;
  22. }
  23.  
  24. void Cliente::setDNI(string DNI)
  25. {
  26.     this->DNI = DNI;
  27. }
  28.  
  29. void Cliente::setEdad(unsigned int edad)
  30. {
  31.     this->edad = edad;
  32. }
  33.  
  34. void Cliente::setNombre(string nombre)
  35. {
  36.     this->nombre = nombre;
  37. }
  38.  
  39. // Defines el metodo como si le pasas un parametro de tipo estado_civil
  40. void Cliente::setEstado_civil(estado_civil civil)
  41. {
  42.     this->civil = civil;
  43. }
  44.  
  45.  

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

JuaNiYoT

  • Nuevo Miembro
  • *
  • Mensajes: 15
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #2 en: Miércoles 13 de Abril de 2011, 11:05 »
0
Muchas gracias me ha quedado clarísimo, muy bien explicado. Un saludo.

JuaNiYoT

  • Nuevo Miembro
  • *
  • Mensajes: 15
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #3 en: Miércoles 13 de Abril de 2011, 11:15 »
0
Otra dudilla, he visto que la definición del tipo enumerado la haces como pública pero que en la clase, pones antes la parte pública que la privada. ¿Eso es mejor hacerlo así?. Lo digo porque si lo haces con la parte pública después no reconoce en la parte privada la definición de la variable de tipo estado_civil. Espero haberme explicado. Gracias y un saludo.

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Problema de novato con clases
« Respuesta #4 en: Miércoles 13 de Abril de 2011, 14:11 »
0
Cita de: "JuaNiYoT"
he visto que la definición del tipo enumerado la haces como pública pero que en la clase, pones antes la parte pública que la privada. ¿Eso es mejor hacerlo así?
Da igual en realidad. Es cuestión de gustos.

Cita de: "JuaNiYoT"
Lo digo porque si lo haces con la parte pública después no reconoce en la parte privada la definición de la variable de tipo estado_civil.
Personalmente pondría en enum en el fichero de cabecera pero fuera de la declaración de la clase. Así podrás usar dicho tipo enumerado en otras clases sólo con incluir dicho fichero de cabecera y no tener que andar definiéndolo de nuevo para cada clase. Todo depende también del diseño de la aplicación y de si dicho tipo va a ser reutilizado. A ver que opina nuestro querido ProfesorX.

JuaNiYoT

  • Nuevo Miembro
  • *
  • Mensajes: 15
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #5 en: Miércoles 13 de Abril de 2011, 16:23 »
0
Al final lo he puesto fuera de la definición de la clase, pues si lo dejaba dentro me daba error. Muchas gracias por las respuestas y otra duda ya que estoy.

¿Cómo se leen los tipos enumerados? Es que ya he visto que con el cin no puedo pero entonces como lo hago?

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #6 en: Miércoles 13 de Abril de 2011, 18:33 »
0
Puedes leerlos a traves de comparaciones para saber cual esta seleccionado, o puedes mostrar su valor (aunque el valor sera un entero que no te servira de mucho).
Mira, aquí te dejo un ejemplo:


Código: C
  1. #include <stdio.h>
  2.  
  3. enum {
  4.         FUET,
  5.         CHORIZO,
  6.         QUESO
  7.         }embutido;
  8.  
  9. int main(int argc, char **argv)
  10.  
  11. {
  12.  
  13.     embutido = FUET;
  14.  
  15.         printf("%dn", embutido);
  16.  
  17.         switch( embutido ) {
  18.  
  19.             case FUET:      printf("Fuetn");
  20.                             break;
  21.  
  22.             case CHORIZO:   printf("Chorizon");
  23.                              break;
  24.  
  25.             case QUESO:     printf("Quesoon");
  26.                              break;
  27.  
  28.         }
  29.  
  30.         return 0;
  31. }
  32.  

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Problema de novato con clases
« Respuesta #7 en: Jueves 14 de Abril de 2011, 09:32 »
0
Leber, el uso de switch en estos casos no es recomendable, es mejor hacer:

Código: C
  1. enum
  2. {
  3.     FUET = 0,
  4.     CHORIZO,
  5.     QUESO
  6. } embutido;
  7.  
  8. char* nombres_embutidos[3] = {"Fuet", "Chorizo", "Queso"};
  9.  
  10. printf("%dn", embutido);
  11. printf("%sn", nombres_embutidos[embutido]);
  12.  
Más rápido, más eficiente, menos código, más legible y más modificable.

Saludos.

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #8 en: Jueves 14 de Abril de 2011, 09:40 »
0
Bueno,  más que nada fue para darme a entender.  :)

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Problema de novato con clases
« Respuesta #9 en: Jueves 14 de Abril de 2011, 09:43 »
0
^_^  ;)

JuaNiYoT

  • Nuevo Miembro
  • *
  • Mensajes: 15
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #10 en: Viernes 15 de Abril de 2011, 14:14 »
0
Gracias por vuestras respuestas, pero la pregunta o no era esa o es que no se puede hacer como yo pienso. Yo lo que quiero es poder almacenar en el tipo enumerado el valor que coges. Por ejemplo
para el tipo de estado civil del que hablo, hacer algo así:

civil=0; //suponía que así guardaría el estado civil para el objeto que esté usando. ¿Como haría eso? pues he visto que no se le pueden asignar ni enteros ni string... por lo tanto estoy un poco perdido. Para que sirve entonces el enum?

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #11 en: Viernes 15 de Abril de 2011, 22:45 »
0
Cita de: "JuaNiYoT"
Yo lo que quiero es poder almacenar en el tipo enumerado el valor que coges.
Supongo que tu querias algo como que estado_civil.soltero = "Soltero", y no, no es asi como funciona el enum. Como te dije antes, el enum internamente se guarda como si fuera un valor de tipo entero, con valores que comienzan en cero y aumentan en uno de forma consecutiva (0,1,2,3, etc) a menos que  en la declaracion le pongas explicitamente que valores tendra el enum.

Citar
suponía que así guardaría el estado civil para el objeto que esté usando. ¿Como haría eso?

Bueno, hay varias formas de hacerlo, la forma como yo lo haria seria algo parecido a como lo hizo Leber, usando switch:

Código: C++
  1.  
  2. int main()
  3. {
  4.     int civil;
  5.     Cliente* cliente;
  6.  
  7.     cliente = new Cliente();
  8.  
  9.     cout << "Estado civil (0=Soltero, 1=Casado, 2=Viudo, 3=Divorciado): ";
  10.     cin >> civil;
  11.  
  12.     switch (civil)
  13.     {
  14.     case Cliente::soltero:
  15.         cliente->setEstado_civil(Cliente::soltero);
  16.         break;
  17.     case Cliente::casado:
  18.         cliente->setEstado_civil(Cliente::casado);
  19.         break;
  20.     case Cliente::viudo:
  21.         cliente->setEstado_civil(Cliente::viudo);
  22.         break;
  23.     case Cliente::divorciado:
  24.         cliente->setEstado_civil(Cliente::divorciado);
  25.         break;
  26.     }
  27.  
  28.     return 0;
  29. }
  30.  
  31.  

De todas formas, necesitarias validar tu entrada para que en civil no guardes valores fuera del rango, es decir, menores a cero o mayores a 3 :)

Citar
Para que sirve entonces el enum?

Bueno, tratare de explicar un poco a ver si comprendes mejor, como dije antes el enum internamente se guarda como un valor de tipo entero. Te permite definir constantes de manera consecutiva y de forma mas facil. Si declaras manualmente tus constantes harias algo como esto:

Código: C++
  1.  
  2. const int soltero = 0;
  3. const int casado = 1;
  4. const int viudo = 2;
  5. const int divorciado = 3;
  6.  
  7.  

A la vez funciona como tipo, lo cual te permite definir una variable de tipo enum, al usar ese tipo, hace que el compilador genere errores cuando tratas de asignar a la variable un tipo inadecuado, ejemplo:

Código: C++
  1.  
  2. // esta linea generara un error
  3. cliente->setEstado_civil(0);
  4. // Esta linea compilara correctamente
  5. cliente->setEstado_civil(Cliente::soltero);
  6.  
  7.  

Aunque puedes hacer un type cast para asignar, ya que un enum y un int son compatibles, pero deberas tener cuidado para no asignar un valor no valido.

Ejemplo de type cast (algo rebuscado):

Código: C++
  1.  
  2.     Cliente::estado_civil edo_civ;
  3.     civil = 0;
  4.     // type cast
  5.     edo_civ = (Cliente::estado_civil) civil;
  6.     cliente->setEstado_civil(edo_civ);
  7.  
  8.  

En el caso anterior, un valor no valido seria hacer civil = 4.

Ojala y te haya quedado un poco mas claro.

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

JuaNiYoT

  • Nuevo Miembro
  • *
  • Mensajes: 15
    • Ver Perfil
Re: Problema de novato con clases
« Respuesta #12 en: Martes 19 de Abril de 2011, 10:51 »
0
Perfecto, ahora si me he enterado de todo. Muchas gracias profesor X por su ayuda y a todos los demás claro está. Voy a probarlo haber que tal ahora. Un saludo.