![]() |
Estudiando constructores y destructores
Segun la documentacion, en el constructor de un objeto todas las referencias a otros objetos son asignadas automaticamente a NIL
Es decir, teniendo esta clase
Esto funciona de maravillas y no he tenido nunca problemas con eso (una vez que lo entendi claro) Hasta que hoy, haciendo experimentos raros, se me ocurrio hacer esto:
Obviamente llamar a FomFoo.Free es seguro, de hecho el destructor no se ejecuta; las variables de instancia son seteadas a nil en los constructores de los objetos (que va, TForm es un objeto tambien, recuerda? :)) Pero el problema son las variables locales; es verdad, de hecho tiene logica, que si yo declaro una variable, y no la inicializo nunca, el valor no esta definido; es decir que una llamada a Free deberia arrojar una excepcion Acess Violation. Bueno, curiosa fue mi sorpresa al correr el codigo anterior: no se elevo ninguna excepcion. Los invito a que ejecuten el mismo codigo :) Para el que no se le ocurra, puede agregar la linea ShowMessage(LocalFoo.ClassName); antes del Free |
Lo he ejecutado.
No se elevan excepciones pero se corrompe la app. Si tratas de hacer esto:
Aparece una excepcion en la línea
Si trato de hacer esto El antivirus se carga el ejecutable y no corre. Saludos. |
Curiosamente, usando el codigo que publicas me da error de access violation, como debe ser
Entonces creo que habra que hilar mas fino: Uso Delphi 2010 y estoy corriendo Windows 10 64 bits En esas condiciones este codigo:
Ejecuta sin problemas: lo que me causo tanta curiosidad es que el Button1 del form desaparecia...entonces, agregando el ShowMessage:
El mensaje imprime "TButton" :D Mas extraño aun, puedo hacer esto sin problemas:
No da error Access Violation!!! No puede ser!! Me imprime "TButton"! Las variantes son infinitas:
|
Este codigo crea un boton con caption "TCustomButton", lo coloca en el formulario, y destruye a Button1. A su vez, asigno el mismo evento que puedo ir invocando una y otra vez y nunca se produce ninguna Access Violation |
Hola Agustin.
Cita:
Por otro lado el método TObject.Free está implementado así, pero por ser LocalFoo una variable local y no estar inicializada, no tendrá el valor nil sino garbage y se llamará al método Destroy sobre la dirección del invocante (Sender en el caso).
Es por eso que se insiste en inicializar las variables locales: Hay casos como el tipo string donde no es necesaria la inicialización, aunque hacerlo no provoca perjuicio alguno. Saludos :) |
Yo creo que hay algo mas
No esta apuntando a garbage como decis: creo que por alguna feliz coincidencia, siempre apunta a Sender Creo que tiene que ver con el codigo que emite el compilador; desgraciadamente, no soy capaz de leer lenguaje ensamblador
|
Hola Agustin.
Cita:
cierra Form1 y deja el proyecto residente en memoria. No sé con seguridad que valor tiene la variable LocalObj al momento de la llamada a Free, pero sin dudas que inicializando la variable local no se produce ninguna anomalía. Saludos :) |
La franja horaria es GMT +2. Ahora son las 23:24:39. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi