Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: tamat en 03 de Enero de 2009, 02:55:05 PM

Título: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 03 de Enero de 2009, 02:55:05 PM
Tengo una clase que deriva de otra, que a su vez deriba de otra:

Texture -> Reource -> Object

El problema surge cuando instancío texture y llamo a un método virtual de texture (que no tienen sus padres) llamado Create, entonces el visual me avisa de que algo raro está pasando porque la pila no encaja bien, entonces debugo y veo que efectivamente al llamar a mi método virtual se me está ejecutando un método totalmente distinto, no el mismo método en la clase padre, directamente uno con parametros y retorno diferente, que obviamente me está dejando la pila hecha un cristo y el visual se da cuenta al ver que no encaja el numero de bytes allocados.

Bien, hasta aquí yo podría pensar - en algun momento he jodido la tabla de funciones virtuales al salirme de algun array o hacer un memset - pero realmente no hay nada raro, creo la instancia, y lo siguiente que hago es llamar al metodo virtual, y los constructores son muy simples, solo ponen a cero las variables (no uso nunca memcpys o memsets, directamente igualo a cero).

Desesperado se me ocurre heredar de Texture una clase Foo, instanciarla y llamar a mi metodo virtual Create, y entonces sí funciona. O sea que Foo sí que deja bien la tabla de funciones virtuales, Texture no.

Intento debugar la tabla para ver si en algun momento se cambia pero en mi tabla de funciones virtuales no sale mi método Create, salen solo los de la clase padre, supongo que el compilador si ve que un metodo no tiene dos implementaciones entonces se ahorra reservarle espacio en la tabla de funciones.

En fin, es desesperante y llevo ya un día perdido con esta chorrada, debería intentar aislar el problema pero es una clase enorme que usa todo mi framework y está jodido.

Si alguien tiene alguna idea se lo agradeceré (aunque como alguien me venga con - has puesto la palabra virtual delante del nombre de la funcion? - me pondré muy tenso... y no quereis que me ponga tenso)
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: Mars Attacks en 03 de Enero de 2009, 03:38:45 PM
¿Qué ocurre si eliminas la cabecera de la función virtual Create? ¿Se queja el compilador? (Dicho de otra forma: ¿encuentra la función aunque no la hubieras declarado?)

Segunda idea: ¿Qué ocurre si añades a los padres la función virtual Create vacía? ¿Sigue funcionando mal?
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: AK47 en 03 de Enero de 2009, 05:57:45 PM
Estas usando punteros o referencias de las instancias, o estas usando las instancias directamente? Pon el codigo relevante del problema, anda :)
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 03 de Enero de 2009, 06:39:29 PM
Respondiendo a Mars:

Si quito la funcion peta el compilador, no tiene pinta de usar otra funcion, de hecho probé de cambiarle el nombre no sea que por Create pillase algo de windows, pero hacía lo mismo

Lo de ponerle la funcion a los padres lo pensé pero por desgracia algunos parametros son enums de la clase Texture así que está dificil, pero lo intentaré cambiando algunas cosas.

Respondiendo a AK:

Uso punteros, podría poner el codigo pero no vereis nada raro, es todo muuuy estandar, por ejemplo:



class Texture : public Resource
{
//...
virtual const char* tellmefoo() { return "foooo!"; }
virtual const char* ozu(int a,int b,int c) { return "foooo2!"; }
};

//...
Texture* texture = new Texture();
texture->ozu(1,2,3);



Al debugar la llamada a ozu veo que entra en tellmefoo.

En fin, entiendo que es un error rarisimo en el que pueden afectar mil cosas, es solo que ha aparecido de la nada y me tiene algo desesperado, tendré que reducirlo a lo minimo... pero joder, para unas navidades que tenía tiempo para programar y me las paso en esta mierda...

Gracias por las respuestas
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 03 de Enero de 2009, 07:43:44 PM
Puestos a aislar he creado esta mini aplicacion donde sucede el error, así que paso a remirar linea a linea los constructores (por eneaba vez)

#include <iostream>

#include "HH.hxx"

void main()
{
HH::Texture* t = new HH::Texture;
t->ozu(1,2,3); //<-- Llama a tellmefoo();
}
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: Buffon en 03 de Enero de 2009, 09:19:03 PM
Perdona si no he entendido bien el código pero, para que usas virtual en la hija ?

virtual es para definir una función que va a ser polimórfica, así la clase será tratada como abstracta y no referenciable y se ponen en los padres, si la defines en el hijo no tiene uso o significado.
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 03 de Enero de 2009, 09:20:34 PM
tal vez porque alguien hereda de Texture y reimplementa ese método... como RenderTexture. En serio, no busco consejos sobre POO, llevo muchos años en el gremio
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: gdl en 03 de Enero de 2009, 09:30:16 PM
En lo que pones no veo nada raro, pero por decir algo que suele ser usual: Las funciones virtuales no se pueden llamar desde los constructores. Lo mismo no es eso, pero para ir  descartando cosas.
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 03 de Enero de 2009, 09:32:33 PM
sip, eso está descartado, de hecho ningun constructor llama a ninguna función.

Pero no le deis vueltas, suena a error muchungo, regiones de memoria que se solapan, algo así, cuando lo descubra ya os lo diré, pero era por saber si alguien había experimentado algo parecido.
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: AK47 en 03 de Enero de 2009, 10:49:25 PM
Poner una funcion a virtual no hace que la clase sea abstracta y no se pueda instanciar, eso solo pasa con las funciones virtuales puras (esos con virtual tralari = 0)
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 03 de Enero de 2009, 11:14:00 PM
pero si aquí nadie está hablando de clases virtuales puras, leñe. Que esto no es un thread de - enseñanos cuanto sabes de POO - sino sobre errores chungos con la tabla de punteros a funciones virtuales.
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: Pogacha en 04 de Enero de 2009, 01:57:17 AM
Has una copia del proyecto entero y ve borrando partes que creas no intervengan, cuando deje de hacer la falla te fijas que cambiaste ultimo.


Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 04 de Enero de 2009, 02:14:10 AM
eso he intentado, pero está dificil porque es un proyecto con demasiadas dependencias. Para colmo he hecho un miniproyecto que usa el framework y al ejecutar me pide la opengl.dll cuando nunca me había pedido esa dll (siempre me pedía la opengl32.dll), alguien sabe qué diferencia hay? yo linko contra opengl32.lib así que no entiendo a qué viene opengl.dll
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: davidgf en 04 de Enero de 2009, 01:08:18 PM
Tienes la posibilidad de probar con otro compilador? Ni que fuera una versión distinta del visual.

Saludos!
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: HarvesterOfAcorns en 04 de Enero de 2009, 02:26:54 PM
Has declarado tus clases en un espacio de nombres? Lo pregunto porque se me ocurre una hipótesis pelín peliaguda, pero dado lo chungo del asunto no estaría de más descartar.

A ver, supongamos que en alguno de los archivos de cabecera que hayas incluido en tu proyecto, digamos alguno de opengl, se define una clase con el mismo nombre que la tuya, Texture, supongamos, y van dos, que alguna de las constructoras de esa clase de ogl admite los mismos argumentos que la constructora de tu clase Texture; supongamos, que pesadito!!!, que esa clase implementa un método que se llama ozu(), esto ya sería la leche de la coincidencia, y por último vamos a suponer que ese método ozu() ejecuta otro método de su misma clase cuando se le llama, supón que es un método privado, y que se llama tellmefoo(), la releche!!!!

Al crear una instancia de Textura el compilador debería cuando menos avisar de que hay dos clases con el mismo nombre y que no sabe a cual te estás refiriendo, salvo que en alguna parte del código haya alguna instrucción del tipo "using namespace espacio_opengl" que le indique al compilador que la clase Texture que ha de instanciar  no es la tuya sino la de ogl.

Además esto también podría explicar el problema de  las dll.

Bueno, ya avisé que era descabellado, igual me he pasao.

Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: AK47 en 04 de Enero de 2009, 02:32:09 PM
Cita de: tamat en 03 de Enero de 2009, 11:14:00 PM
pero si aquí nadie está hablando de clases virtuales puras, leñe. Que esto no es un thread de - enseñanos cuanto sabes de POO - sino sobre errores chungos con la tabla de punteros a funciones virtuales.

Lo decia por lo que ha comentado Buffon, na mas ;)
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 04 de Enero de 2009, 02:46:38 PM
HarvesterOfAcorns uso un namespace propio, así que descartado.

AK47, sorry, estoy algo susceptible
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: fjfnaranjo en 06 de Enero de 2009, 02:28:10 PM
¿Cómo llevas el tema tamat? Tengo bastante curiosidad por saber si es o no del compilador...
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: tamat en 06 de Enero de 2009, 04:25:10 PM
Tiene toda la pinta, mañana lo probaré en el trabajo a ver, porque he reducido el problema al absurdo y sigue sucediendo. Os mantendré informado.

Yo creo que es porque linko contra una LIB creada por mi y algo pasa (pese a usar el mismo convention en todo y haber funcionado siempre).

De hecho si omito la llamada a la función que me daba problemas todo lo demas funciona perfectamente, lo cual lo hace aun más extraño.
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: Pogacha en 08 de Enero de 2009, 02:02:40 AM
Compilas con una cabecera y linkeas con otra!!!!!!
jaajajaj
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: AK47 en 08 de Enero de 2009, 08:45:05 AM
No olvidarse tampoco del "Rebuild All" o similares, que algunas veces queda morralla por ahi que hace que todo se vaya al traste  >.<
Título: Re: Problema con funciones virtuales, se llama a la que no és.
Publicado por: davidgf en 08 de Enero de 2009, 10:14:42 PM
jo tamat nos vas a dejar con la intriga! gcc power!!!