![]() |
![]() |
![]() |
![]() |
![]() |
FTP | ![]() |
![]() |
CCD | ![]() |
![]() |
Buscar | ![]() |
![]() |
Trucos | ![]() |
![]() |
Trabajo | ![]() |
![]() |
Foros | ![]() |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
![]() |
|
Herramientas | Buscar en Tema | Desplegado |
#41
|
||||
|
||||
![]() Pues aunque no lo creas, yo tampoco conosco una solucion efectiva...
![]() Pero como puedes ver en mi Delphi 7 nunca se ejecuta la segunda instruccion, lo cual me parece misterioso, ya que tal solucion es válida para otros lenguajes de programacíon como por ejemplo C++, Java. ![]() Rogaría a algun miembro que tenga las últimas versiones de Delphi a que pruebe y nos comente... ![]() Saludos... ![]()
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7 |
#42
|
||||
|
||||
Hola Roberto.
Me resulta algo humorística la forma en que afrontas a Román en los últimos mensajes, pero tal humorismo surge principalmente por la combinación de dos cosas: la idea (interesante, por cierto) de que una clase sea capaz de conocer todas las referencias a sus instancias, y por otro lado, que no pareces tener muy claro lo que Self significa en Delphi (y claro, también por tantas caritas ![]() No sé por qué en otros lenguajes se permite la sentencia que señalas (y me gustaría saber), mas en Delphi Self es un parámetro, no declarado, de todos los métodos, y es básicamente la instancia para la cual se está ejecutando el método (intuyo que esto de alguna forma ya lo sabías). Ignoraba que Delphi "permitiese" referencias de escritura en el parámetro Self (para mí siempre ha sido una referencia de solo lectura), pero no me extraña en absoluto que el compilador la deseche sin generar instrucción máquina alguna para esa sentencia (lo puedes verificar con la ventana CPU). Y es que Self no podría ser variable objeto alguna, todas las variables objeto son punteros (apuntadores) hacia la región de memoria donde se encuentra un "Self", es decir, donde se encuentra una instancia de objeto. Entonces, si se pudiera asignar Nil a Self, lo que se estaría poniendo en blanco sería esa instancia, no las variables que apuntan a ella. Ahora, aunque hay argumentos muy sólidos para proponer que las clases no conozcan sus instancias y las referencias a éstas, hay casos donde sí pudiera ser conveniente una capacidad similar. Yo tengo una clase derivada de TClientDataSet, con varios métodos que necesitan conocer cuáles otras instancias de la clase comparten la misma base (propiedad DSBase). Lo solucioné con una lista privada (declarada como variable global en la sección Implementation), y usando el constructor para agregar cada nueva instancia a la lista y el destructor para quitar tal instancia de la lista.
Independientemente de lo que dicten los cánones de la POO, esta implementación me resulta eficiente para mis propósitos. Sin embargo, esto es sólo mantener una lista de las instancias creadas de una clase, mas no de las variables que hacen referencia a dichas instancias. Si quisiéramos que se mantuviera también una lista de tales referencias entraríamos a un terreno un tanto peliagudo, ya que implicaría necesarias modificaciones al compilador Delphi mismo, a fin de que siempre que se ejecute una asignación de instancia de objeto a una variable, tal variable se "marque" para ser limpiada cuando el objeto se destruya:
O bien, que no fuese obligatorio "fichar" a la variable, e implementar nosotros mismos un mecanismo "casero" general, con una lista global y una par de funciones AssignObj y FreeObj: Lo pongo como ejemplo, pero lo desaconsejo, porque ¿cómo resolver un caso como este?:
Ahora, sí se realizaran las modificaciones al compilador para que toda asignación de objeto guardara en una lista interna la variable a la cual se asigna, de tal forma que al destruirse tal objeto todas las variables que apunten a él se pongan en Nil, habría que considerar lo mismo para los parámetros de las funciones: Agrego: Y que las variables y parámetros se eliminaran de dicha lista interna al quedar fuera de ámbito. Como podrás ver, son varias y muy importantes las implicaciones que tendría modificar el compilador para que las variables objeto nunca apunten a los vestigios de una instancia (es decir, para que se vuelvan Nil cuando la instancia sea destruida). Pero sí es posible crear una clase particular con este comportamiento, donde esa clase mantenga una lista de punteros, que no serían punteros a las instancias, sino punteros a las variables objeto. De tal forma que el destructor de la clase se encargue de recorrer esa lista y poner a cada variable objeto en Nil. Sin embargo, esto requeriría de un "contrato" entre el creador de la clase y el programador que la usara. Algún párrafo de documentación donde se le diga algo como: Si usted quiere que una variable objeto de esta clase sea limpiada automáticamente, debe usar el método AssignToVar:
Yo solía hacerme este tipo de planteamientos casi filosóficos, al grado de crear rutinas de código extravagantes. Con el tiempo uno se va dando cuenta de los pros y contras de cada técnica, hasta que se tiene algún grado de experiencia como para proponer cambios en un lenguaje o en un compilador. Al menos a mí, me gustaría que las clases tuviesen mecanismos nativos para conocer todas sus instancias; pero si esto sonara como un disparate, quizá se deba a que me falta experiencia para darme cuenta de que eso sería un despropósito, o quizá no. ![]() Pero tratándose de variables objetos, creo que lo mejor es seguir dejando la responsabilidad en manos del programador que declara y hace uso de esas variables; algo que me parece Román ya te había comentado. Un abrazo objetivo. Al González. Última edición por Al González fecha: 07-04-2011 a las 23:30:27. |
#43
|
||||
|
||||
Cita:
Si es solo para lectura y ha sido pensado para eso, pues creo que debería mostrar un error¿verdad? o no permitir directamente tal instruccion y es por eso mi confucion. ![]() Como dije claramente en mi anterior post no tengo una solucion para lo que se pretendía hacer, el hecho de que hubiera hecho uso de Self, fué solo un intento y creo que lo explique claramente. ![]() La verdad que me has abierto nuevas perpectivas.. ![]() ![]() Cita:
Teniendo creado(instanciado) un formulario de una determinada clase de la siguiente forma: y sabiendo que en la clase TChildForm en su evento OnClose tenemos Ahora el asunto es: ¿cómo lograr saber que el objeto al que hace referencia la variable "MyForm" ha sido liberado? ![]() OJO: todos sabemos que cuando un objeto se libera, pues la referencia que le apuntaba de igual forma sigue referenciando a la misma direccion de memoria donde estaba el objeto.Es decir el espacio de memoria del objeto se libero pero su apuntador(referencia) sigue apuntadolo. Pues ..en lo anteriores post hemos discutido que la solucion sería poner al apuntador en nulo (nil)despues de la destruccion del objeto y luego para saber si la referencia apunta a un Objeto válido podriamos poner o bien usando la funcion Assigned Ahora vá la pregunta ¿Existe alguna forma de determinar que la referencia de un objeto apunta a un objeto no destruido sin estar poniendola a nulo cada vez que se libera el objeto?. Es decir.. yo como programador pienso y digo hipoteticamente:"No quiero que la referencia del objeto se ponga en nulo al momento de destruirse el objeto , más bien quiero que siga apuntado a la misma direccion aunque el objeto ya esté liberado" Pero si más adelante en mi código quisiera saber si el objeto fue destruido o nó ¿como lo haría? ¿? qué código debiera poner en lugar de o bien ¿Cómo lo soluciono? ![]() ![]()
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7 |
#44
|
||||
|
||||
Cita:
Cita:
Pero ahora que vuelvo a leer el planteamiento de parte tuya, recordando que GetMem y FreeMem son las funciones que utiliza nativamente una clase para reservar y liberar el bloque de memoria de la instancia, y que tales funciones son reemplazables ![]() El inconveniente a resolver sería el de las coincidencias de bloques, es decir, aquellos casos donde una nueva instancia de objeto venga a ocupar la parte inicial (o el bloque de memoria completo) que ocupaba previamente otro objeto ya destruido. Quizá una solución a esto sería hacer que GetMem desplace el bloque que devuelve para que no haya coincidencias o algún control similar, pero eso haría crecer constantemente la memoria usada por la aplicación, por lo que se necesitaría de cierta ayuda de parte del programador, como para decir "estas variables ya no me interesa evaluar", lo cual nos remite, una vez más, a la recomendación de que cada programador se haga responsable de la vida de sus variables objetos. No obstante el antojo de darle algunas vueltas más la tuerca persiste, e intentar lo que comento de GetMem y FreeMem puede ser cuando menos un ejercicio interesante (sin olvidar que esas funciones no sólo se utilizan para instancias de objetos). ![]() Saludos. Al González. |
#45
|
||||
|
||||
![]() Cita:
![]() Cita:
![]()
![]() Como podrás ver, si se puede lograr la primera opcion creo que ya la cosa se soluciona...ALELUYA.. ![]() ![]() ![]() Saludos... ![]()
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7 |
#46
|
||||
|
||||
Resp
No se cuando tiempo tienen este hilo.
Este es el codigo de freeAndNil
Primero Nil Y Luego Free. Parece ilogico. pero no hay perdida de memoria.
__________________
Todo se puede, que no exista la tecnología aun, es otra cosa. |
![]() |
|
|
![]() |
||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Forms: FreeAndNil ó Release y la validación Assigned? | jbautista | Varios | 13 | 09-02-2010 17:33:03 |
Assigned y Free | gluglu | Varios | 4 | 14-05-2007 21:03:37 |
Problemas FreeAndNil | OscarG | OOP | 4 | 09-11-2005 12:48:46 |
Free Pascal 2.0 | marcoszorrilla | Noticias | 6 | 19-05-2005 12:04:51 |
Componente free... | Mauro® | Varios | 10 | 12-06-2004 13:15:24 |
![]() |
|