Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: t4r0x en 12 Diciembre 2014, 02:10 am



Título: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 02:10 am
buenas a todos veran tengo problemas al intentar compilar el codigo de abajo, lo que quiero hacer en obtener el puntero de un funcion miembro de una clase, guardarlo en la estructura y luego llamar a esa funcion... pero me esta dando problemas al compilar y no comprendo porque, probe con el puntero this pero nada, talvez usando static pero no quiero hacer todas las funciones de la clase estaticas porque son muchas y prefiero no usar static.

podria alguien decirme porque no funciona y alguna solucion? gracias

Código
  1. int  main()
  2. {
  3.    MiClase c1;
  4.    estructura es;
  5.  
  6.    c1.funcion2(&es);
  7.  
  8.    return 0;
  9. }
  10.  
  11.  

prueba.h
Código
  1. class MiClase;
  2.  
  3. typedef int(MiClase::*puntero1)(int);
  4.  
  5. typedef struct _estructura
  6. {
  7.    puntero1 p1;
  8.    int n1;
  9.    int n2;
  10.    int n3;
  11.    int n4;
  12.  
  13. }estructura;
  14.  
  15. class MiClase
  16. {
  17. public:
  18.    int funcion1(int valor);
  19.    void funcion2(estructura* datos);
  20.    int funcion3(estructura* datos);
  21.  
  22. };
  23.  

prueba.cpp
Código
  1. #include "prueba.h"
  2.  
  3.  
  4. int MiClase::funcion1(int valor)
  5. {
  6.    return valor + 40;
  7. }
  8.  
  9. VOID MiClase::funcion2(estructura* datos)
  10. {
  11.    datos->p1 = funcion1;
  12.    datos->n1 = 10;
  13.    datos->n2 = 20;
  14.    datos->n3 = 30;
  15.    datos->n4 = 40;
  16. }
  17.  
  18. int MiClase::funcion3(estructura* datos)
  19. {
  20.    datos->p1(10);
  21. }
  22.  


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: eferion en 12 Diciembre 2014, 07:45 am
A ver, los punteros a funciones miembro no funcionan exactamente igual que los punteros a funciones que, imagino, estás acostumbrado a usar.

Código
  1. class POO
  2. {
  3.  public:
  4.    int funcion( );
  5. }

Si yo creo 20 instancias de la clase que he declarado encima de esta línea, en el código no voy a encontrar 20 copias de "funcion". Únicamente habrá una y será compartida por todas las instancias de "POO". Esto quiere decir que, aunque tu veas que la firma de la función es, símplemente, "int funcion( );", internamente esta función ha de recibir un puntero que apunte a la instancia de "POO" sobre la que tiene que trabajar.

El ejemplo que tu has puesto te podría servir, con algún retoque, para referenciar funciones miembro estáticas, pero no te sirve para funciones miembro dependientes de la instancia. Si quieres acceder a una función no estática necesitas facilitar una instancia de FOO válida.

Lo que pretendes hacer tiene mejores soluciones:

* Guardas simplemente un puntero a "MiClase" en la estructura.
* Haces que "funcion1" sea estática, dado que no accede a elementos no estáticos de la instancia "no vas a tener problemas
* Te replanteas el diseño. Esta opción es la recomendada salvo que estés haciendo una práctica. Este tipo de códigos complican muchísimo el mantenimiento de una aplicación.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 08:31 am
La verdad es que estoy pasando una aplicacion entera a codigo C++ e implementarlo en clases entonces el codigo fuente de la aplicacion tiene mas 20,000 lineas de codigo entre todos los archivos .cpp y .h y se me haria complicado rehacer la aplicacion, y por eso simplemente no quiero tocar nada del codigo e implementar las funciones dentro varias clases, tengo casi todo el codigo listo solo me falta esa parte en donde no puedo encontrar una solucion :/


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: eferion en 12 Diciembre 2014, 08:45 am
Migrar aplicaciones siempre es complicado y, por experiencia, considero un error intentar que la migración reproduzca de forma totalmente fiel la arquitectura anterior.

El problema que se suele producir es que el código acaba siendo poco amigable, ya que cada lenguaje tiene sus propias características y cosas que en un lenguaje se hacen de una forma, en otro deben hacerse de forma totalmente diferente. Esto hace que aparezcan estructuras raras y poco claras que acaban dando problemas.

Si el código va a acabar siendo el mismo entonces no vas a obtener ninguna ventaja por la migración.

Mi consejo es que las partes feas como estas reciban un repaso y se refactoricen como es debido. Se que al final es como todo, hay dinero de por medio que limita el alcance de todo proyecto, pero una arquitectura bien hecha reduce muchísimo el mantenimiento futuro... es elegir entre pagar un poco más hoy o un mucho más mañana.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 08:56 am
No perdon quiza escribi mal pero la aplicacion esta en C/C++ pero no es implementada en clases asi que lo que estoy haciendo es simplementa creando clases para cada cpp o para cada grupo de funciones que se relacionen, la verdad es que en el codigo original no veo que sea raro ya que se inicializa esa estructura con algunos valores y punteros a funciones para luego usar esos punteros dentro de otras funciones... y si declaro a funcion como estatica en la clase el compilador me dice que las demas funciones deben ser estaticas tambien y el resto de funciones llaman a otras y asi, al final el compilador me muestra cientos de errores... asi que simplemente queria saber como arreglar eso, la verdad me parece extraño no poder compilar eso... ya uqe tiene algo sentido hacer lo que estoy haciendo... creo :P


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: eferion en 12 Diciembre 2014, 09:14 am
Código
  1. class FOO
  2. {
  3. public:
  4.  
  5.  void func1( )
  6.  {std::cout << "func1" << std::endl;
  7.  
  8.  void func2( )
  9.  { func3( ); }
  10.  
  11.  void func3( )
  12.  { std::cout << "func3" << std::endl; }
  13. };

En este ejemplo, tanto func1 como func3 pueden pasar a ser estáticas sin ningún problema, ya que no arrastran dependencias a miembros no estáticos.

Sin embargo, para pasar "func2" a estática sería necesario hacer "func3" también estática, ya que func2 depende de "func3" y una función estática no puede acceder directamente a los miembros no estáticos de una clase.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 09:25 am
pero lo que pasa es que ese es solo un ejemplo lo mas sencillo que pude para poder plantear la pregunta :P ya que en el codigo que quiero resolver hay muchas funciones y variables que se llaman entre si... ademas no puedo definir la funcion dentro de la definicion de la clase ya que hay algunas funciones que necesitan punteros a estructuras definidas que estas mismas necesitan typedef de punteros a otras funciones y pobre con haciendo forwarding de algunas estructuras y clases pero el lio se hace bastante extenso y al final no me resuelve nada.

Y si como le dije no quiero definir las funciones como estaticas porque me resultan cientos de errores.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: eferion en 12 Diciembre 2014, 09:30 am
ok ok, yo el planteamiento que te he dicho parte del desconocimiento más absoluto del código con el que estás trabajando. Obviamente sin tener código es difícil dar soluciones concretas.

En cualquier caso, que te sea breve :)

Un saludo.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 16:42 pm
alguien sabe porqué ese codigo de arriba no compila y darme una solucion a ese codigo?


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: Eternal Idol en 12 Diciembre 2014, 18:34 pm
http://www.parashift.com/c++-faq/memfnptr-vs-fnptr.html


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 19:58 pm
http://www.parashift.com/c++-faq/memfnptr-vs-fnptr.html
pero ya dije que no quiero hacer la funcion estatica porque hace que el codigo tenga mas errores tipo en cascada... yo quiero saber si existe una manera de resolve mi codigo de la manera que intento hacerlo sin static


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: eferion en 12 Diciembre 2014, 20:15 pm
Y tan complicado es almacenar el puntero a la clase en vez del puntero a la función??

Si tienes que hacer artificios así, te lo repito, es porque esa función debería ser estática... que te salen errores en otros métodos??? bueno, lo mismo también deberían ser estáticos.

En serio, hacer una migración a clases... pero haciendo que el código sea el mismo que cuando no había clases no tiene demasiado sentido.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 20:28 pm
si guardo un puntero a la clase deberia modificar casi todo el codigo... bueno tampoco el codigo es tan complejo incluso tiene tipo estructura ideal para hacer clases ya que tiene funciones de inicializar que tengo llamar antes de usar alguna otra funcion para establecer unas estructuras que usara las cuales ya he copiado al cuerpo de la clase y he copiado esas funciones de inicializacion en la funcion constructor, en resumen todo esta bien solo que no compila esa parte que tengo problemas...


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: x64core en 12 Diciembre 2014, 20:45 pm
alguien sabe porqué ese codigo de arriba no compila y darme una solucion a ese codigo?
Has intentado con el operador ->* / .* ?
Además la manera que estas intentando obtener un puntero a la función miembro es incorrecta, allí podria haber cualquier función que podría llamarse "funcion1", mas si la función miembro es global. Esto para obtener el puntero:

&Clase::Funcion

Al llamar:

Código:
this->*

-

En tu caso linea 20:
Código:
(this->*datos->p1)(10);

El código compila y funciona como supongo que quieres que lo haga pero si la aplicación no funciona no seria ese el problema.


Título: Re: AYUDA: problema con funcion miembro de clase
Publicado por: t4r0x en 12 Diciembre 2014, 20:57 pm
Muchas gracias me compilo y la aplicacion funciona!  ;-)