Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-09-2019
josepicd josepicd is offline
Miembro
 
Registrado: jun 2015
Posts: 57
Poder: 9
josepicd Va por buen camino
Clases recursivas, ¿Como hacerlo?

Supongamos que tengo 3 .pas con 1 clase cada uno

La clase 1 contiene un objeto de clase 2 y otro de clase 3.
La clase 2 no contiene nada relevante
La clase 3 contiene un puntero del objeto de la clase 1.

Al meter los uses de da error de redundancia como es de esperar, ¿Como puedo solucionar esto?


----------- file_1.pas --------------------------------------------
uses file_2, file_3;

PC1 = ^TC1;
TC1 = class
f2 : TC2;
f3 : TC3;
end;
----------- file_2.pas --------------------------------------------
TC2 = class
...
end;
----------- file_3.pas --------------------------------------------
uses file_1;

TC3 = class
ptrC1 : PC1
...
end;
Responder Con Cita
  #2  
Antiguo 23-09-2019
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 a todos,

Una posible solución puede ser declarar los miembros como "TObject": tú sabes que el objeto será del tipo que sea, y, podrás hacer el "cast" correspondiente, pero, las unidades que declaren dicho tipo podrán ir en la claúsula "implementation", evitando el tipo de error que comentas.

De todas formas, a ver si algún compañero puede dar alguna otra solución.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 23-09-2019 a las 20:57:56.
Responder Con Cita
  #3  
Antiguo 23-09-2019
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Cita:
Empezado por dec Ver Mensaje
Hola a todos,

Una posible solución puede ser declarar los miembros como "TObject": tú sabes que el objeto será del tipo que sea, y, podrás hacer el "cast" correspondiente, pero, las unidades que declaren dicho tipo podrán ir en la claúsula "implementation", evitando el tipo de error que comentas.

De todas formas, a ver si algún compañero puede dar alguna otra solución.
Esa podria ser una solución, pero si existe la opción de definir las clases en la misma unidad, se resolvería el tema de la referencia circular, asi:
Código Delphi [-]
TC3 = class ; //indica que hay una clase llamada TC3 que se definirá mas adelante

TC1= class
  f3: TC3;
end;

TC3= class
  f1: TC1;
end;

Por otro lado, no entiendo la necesidad de PC1 = ^TC1;...
Responder Con Cita
  #4  
Antiguo 23-09-2019
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Otra opción es usando interfaces, un ejemplo:

Código Delphi [-]
unit uInter;  

interface

type   
  IClase2 = interface   ['{20FF5573-4A4A-4B1F-975B-817714250A03}'] // ( Ctrl+Shift+G )
    function GetValue: Integer;                  
    procedure SetValue(const  Value:Integer);
 end;

implementation

end.

Código Delphi [-]
unit Unit1; 

interface

uses  uInter; 

type
  TClase1 = class(TObject)
  private
    FValue : Integer;
  public
    Clase2: IClase2;
    constructor Create;
    property Value: Integer read FValue write FValue;
  end;

implementation

constructor TClase1.Create;
begin
  FValue := 111;
end;
end.

Código Delphi [-]
unit Unit2;

interface

uses Unit1, uInter;

type
  TClase2 = class(TInterfacedObject, IClase2)
  private
    FValue : Integer;
  public
    Clase1: TClase1;
    constructor Create;
    function GetValue: Integer;
    procedure SetValue(const  Value:Integer);
  end;

implementation

constructor TClase2.Create;
begin
  FValue := 0;
end;

function TClase2.GetValue: Integer;
begin
  Result := FValue;
end;

procedure TClase2.SetValue(const Value: Integer);
begin
  if Value <> FValue then
    FValue := Value;
end;
end.

Código Delphi [-]
program Project1; {$APPTYPE CONSOLE} {$R *.res}

uses
  System.SysUtils,  Unit1 in 'Unit1.pas',  Unit2 in 'Unit2.pas',  uInter in 'uInter.pas';

var
  Clase1: TClase1;
  Clase2: TClase2;
begin
  // Prueba Clase1
  Clase1 := TClase1.Create;
  Clase1.Clase2 := TClase2.Create;
  Clase1.Value  := 111;
  Clase1.Clase2.SetValue(222);
  Writeln(Clase1.Value, ' ', Clase1.Clase2.GetValue);

  // Prueba Clase2
  Clase2 := TClase2.Create;
  Clase2.Clase1 := TClase1.Create;
  Clase2.Clase1.Value := 333;
  Clase2.SetValue(444);
  Writeln(Clase2.Clase1.Value, ' ', Clase2.GetValue);
 
...

end.
Hay que tener en cuenta que en la interface hay que declarar funciones y procedimientos para acceder o modificar las variables de la clase.


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 23-09-2019
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Creo que lo más sencillo es hacer esto:


Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, 

  unit2, unit3;   //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

type
  TForm1 = class(TForm)
  private
  public
  end;

var
  Form1: TForm1;

implementation


{$R *.dfm}
.........
.........
.........


Código Delphi [-]
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus;

type
  TForm3 = class(TForm)
  private
  public
  end;

var
  Form3: TForm3;

implementation

uses unit1;  //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

{$R *.dfm}
.........
.........
.........




Saludos.
Responder Con Cita
  #6  
Antiguo 24-09-2019
josepicd josepicd is offline
Miembro
 
Registrado: jun 2015
Posts: 57
Poder: 9
josepicd Va por buen camino
Aqui el problema que tengo es que el uses debe ir en el interface ya que el TForm3 tiene una variable del tipo TForm1 por lo que si lo saco de la implementation y lo pongo en interface tengo el problema de los uses ciclicos


Cita:
Empezado por escafandra Ver Mensaje
Creo que lo más sencillo es hacer esto:


Código Delphi [-]
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus;

type
  TForm3 = class(TForm)
  private
F1 : TForm1;
public end; var Form3: TForm3; implementation uses unit1; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< {$R *.dfm} ......... ......... .........




Saludos.
Responder Con Cita
  #7  
Antiguo 24-09-2019
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Ten en cuenta que clases recursivas muchas veces es un anti-patron.

Igual a que esas clases sean forms (deberias comunicar datos, no formularios).

En Delphi, una manera elegante de resolverlo es con interfaces. Puedes implementar interfaces para comunicar datos y transpasar "fronteras" manteniendo los principios de

SOLID.

P.D: Algo que he aprendido luego de usar mas de 12 lenguajes es que cuando algo se hace "dificil" es, muchas veces, el mismo lenguaje indicando que hay otro camino mejor y mas idiomatico.
__________________
El malabarista.
Responder Con Cita
  #8  
Antiguo 24-09-2019
josepicd josepicd is offline
Miembro
 
Registrado: jun 2015
Posts: 57
Poder: 9
josepicd Va por buen camino
Muchas gracias a todos, al final he encontrado la forma de sacarlo de interface y meterlo en implementacion, asi todo resuelto.


Gracias por el esfuerzo
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
como hacerlo?¿ tiagor64 Conexión con bases de datos 4 09-02-2005 15:55:04
Como puede hacerlo? Wascar SQL 2 27-12-2004 14:34:57
Cómo hacerlo ... Jordy Conexión con bases de datos 2 19-08-2004 10:21:39
Cómo hacerlo instalable ? K4RL0S Varios 1 03-01-2004 14:50:31
No se como hacerlo apolo18 Impresión 4 19-05-2003 23:13:27


La franja horaria es GMT +2. Ahora son las 11:15:36.


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