Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-11-2006
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Funciones que devuelven objetos

En un proyecto que estoy haciendo se me ocurrió una función que me devolviera un objeto pero me encuentro en una interrogante: Si devuelve un objeto...¿Quien lo crea? la función o quien llama a la función?

Código Delphi [-]
Function GetTabla(nombre:String):TDataset;
var aTabla: TDataset
Begin
    aTabla := Tdataset.create(nil);
    GetTabla := aTabla;  // devolver la tabla recien creada
                                 // pero entonces...quien la destruye?¡???
                                // no se pierde al salir de la función??
end;
 
Procedure HazAlgo;
var unaTabla: TDataset;
Begin
   unaTabla := GetTabla("datos");   ///<--- Se puede hacer esto???
                                               // Pero si unaTabla no se ha construido?     
end;

Mi Teoría:

Se supone que todas las instancias de un objeto son simples punteros partimos de que en la funcion HazAlgo efectivamente unaTabla, al no crearse no reserva memoria para el objeto TDataset, esto lo hace la funcion GetTabla dentro de su codigo y devuelve el puntero a la memoria recientemente reservada (la funcion no la libera destruyendo el objeto que creo). Entonces asumo que unaTabla apunta al Objeto que cre{o la función, por lo que entonces, tendré que destruir directamente unaTabla para liberarla.

Quedando así:
Código Delphi [-]
Procedure HazAlgo;
var unaTabla: TDataset;
Begin
   unaTabla := GetTabla("datos");   //equivaldría a Tdataset.create(nil)
  Try
    { uso una tabla
     .
     .
     .
     }
  finally
    unaTabla.free; // Libero la memoria
  end;
 end;

Segun mi teoria este último código debe ser completamente válido...pero no lo sé hasta probarlo..

Alguna sugerencia? A lo mejor no estoy descubriendo nada nuevo...
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #2  
Antiguo 24-11-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Está bien lo que haces. La función es la que crea el objeto y quien lo recibe se encarga de destruirlo.

// Saludos
Responder Con Cita
  #3  
Antiguo 24-11-2006
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Gracias Roman. Ya lo probe y si era asi como tu bien me confirmas.

Que feo es cuando deja uno algo y luego lo retoma...se te barren muchas cosas
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #4  
Antiguo 25-11-2006
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 28
Lepe Va por buen camino
Para estos temas soy muy quisquilloso, cambiaría el nombre de la función a "CreateTable", "CreateDataset", "AllocDataset", es decir, un nombre que al verlo en la función HazAlgo, identifique que AllocDataset crea internamente un Dataset y por tanto en HazAlgo tengo que destruirlo con free.

"GetDataset" a mí personalmente, no me indica si realmente se crea algo, o es un apuntador a un dataset existente. El hecho es que siempre se me olvida que tengo que destruirlo y acabo revisando el código fuente de "GetDataset" (perdiendo más tiempo). Con un nombre más apropiado, el código se hace más entendible.

saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente,
se lo volveré a explicar hasta que no lo entienda, Gracias.
Responder Con Cita
  #5  
Antiguo 25-11-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Lepe
Para estos temas soy muy quisquilloso
¡Y qué bueno que lo seas! Estoy totalmente de acuerdo contigo. Semánticamente debe quedar claro que la función es una creadora o fábrica de objetos. Me alegra que hayas hecho la observación.

// Saludos
Responder Con Cita
  #6  
Antiguo 25-11-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Pues yo, puñeteramente, pregunto, porque dudo: el identificador puede dejar claro que se creará un objeto, estamos de acuerdo, pero, ¿queda claro que dicho objeto habremos de liberarnos nosotros? ¿Habría alguna forma de dejar esto claro también -a lo mejor ya lo está y a mí no me lo parece- o acaso es algo que hay que dar por sabido? ¿Eh? ¿Eh? ¿Eh?
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #7  
Antiguo 25-11-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Claro, podrías poner:

Código Delphi [-]
Persona := CrearPersonaPeroNoOlvidesLiberarla();

pero lo veo innecesario porque en principio uno sabe como funciona el lenguaje: todo lo que se crea debe destruirse. Si te queda claro que después de

Código Delphi [-]
Persona := TPersona.Create;

debes en algún momento destruir el objeto Persona, no veo por qué no había de ser igualmente claro en el otro caso.



// Saludos
Responder Con Cita
  #8  
Antiguo 25-11-2006
Avatar de yusnerqui
yusnerqui yusnerqui is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuba
Posts: 679
Poder: 21
yusnerqui Va por buen camino
Seguramente voy a decir una de mis acostumbradas burradas, pero en fin, después que me regañen voy a leer un poco más al respecto.

Cita:
Empezado por Roman
todo lo que se crea debe destruirse
A no ser que uses interfaces, pues estas lo hacen por si sola, esto es cierto verdad???

pero lo que tengo es que leer más acerca de estas cosas mágicas que se dan cuenta cuando ya uno no las necesita más, y paff, se suicidan

Saludos
__________________
Lo importante no es llegar primero, sino saber llegar.

Para que puedas llegar mejor lee la Guia de Estilo

Responder Con Cita
  #9  
Antiguo 25-11-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por yusnerqui
A no ser que uses interfaces, pues estas lo hacen por si sola, esto es cierto verdad???
No exactamente. Cada vez que se agrega una referencia a una interfaz (cualquier variable a la que le asignes una interfaz), el compilador agrega una llamada al método _AddRef, y cada vez que se pierde una referencia (por ejemplo, cuando una variable que tenía asignada una interfaz sale de alcance o cuando le asignas otra cosa) el compilador agrega una llamada a _Release.

Aunque semánticamente _AddRef y _Release parecen agregar una referencia y quitarla, lo cierto es que no hacen nada por sí solas, porque, de hecho no existen.

Como sabrás, una interfaz no implementa nada por si sola, sino que se limita a a definir un conjunto de métodos. Una clase puede implementar una o más interfaces, y será esa clase entonces quien realmente haga la implementación de los métodos.

La interfaz base, IInterface, declara tres métodos: QueryInterface, _AddRef y _Release.

Cuando se trabaja con interfaces, se suele derivar la clase que las implemente de TInterfacedObject, que es un objeto que implementa los métodos de IInterface, de manera que nosotros no tengamos que preocuparnos por hacerlo.

TInterfacedObject es quien realmente implementa el manejo automático de la destrucción. Para ello lleva un campo interno FRefCount, que incremente en 1 cada vez que se llama a _AddRef y lo decrementa en 1 cada vez que se llama a _Release. Cuando el método _Release deeca que _RefCount llega a cero, entonces se "suicida".

Sin embargo, puedes usar otros objetos base o implementar tú mismo _AddRef y _Release, de manera que no destrutan el objeto.

// Saludos
Responder Con Cita
  #10  
Antiguo 25-11-2006
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Tienen razon en la observación. De hecho Puse Get por decir cualquier otra cosa ya que como sabemos Get indica que estamos accediendo a una propiedad de un objeto. Yo creo que basta con Agregar "Create" al nombre del método y con eso será suficiente para que casi por costumbre le agreguemos el consabido try..finally que se acostumbra y liberemos la instancia.
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #11  
Antiguo 26-11-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Sí; ahora se me ocurre "otra forma" de verlo. Resulta que si se deja claro, por medio de su identificador, que se creará un objeto en la función "X", lo cierto es que lo creas para algo, y luego de la llamada a la función "X" tú haces uso del objeto... ya esto debería dejar claro que alguien tendrá que liberar el objeto... y ese alguien será uno mismo... o una función "Y", vamos... ¡Patente, patente, aquí hay patente! Soy un genio,... ¡si es que soy un genio! Muack, muack, muack (yo, besándome a mí mismo conmigo mismo).
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Devuelven el dinero de Windows a usuario de Linux Casimiro Notevi La Taberna 1 10-11-2006 00:06:33
Acerca de objetos 3d MakinaX Gráficos 4 19-06-2006 18:56:03
Gestión de queries que devuelven resultado nulo papulo Conexión con bases de datos 7 11-04-2006 18:08:48
Objetos jfontane Varios 1 04-07-2003 15:39:04
Metodos que devuelven referencias a sí mismos shaktale OOP 8 07-06-2003 03:04:12


La franja horaria es GMT +2. Ahora son las 18:48:57.


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
Copyright 1996-2007 Club Delphi