Doubt referring to circular reference of the type client - room

2

Well, I had asked but I think it was not clear so I'll edit it as I suggested, basically I wanted to do an application in Delphi using a TSala class and several TPessoa classes, however, the class TPessoa needs to refer to TSala to be able to pick up information and modify it when necessary, and the room class needs a reference to the class to be able to create a list of people in the room and be able to modify these people.

For example: Do something like this somewhere in the class Personal:

self.sala.pegarPessoaPorNome("Alberto").Dar("Refrigerante");

In the TSala class, it would look something like this:

function pegarPessoaPorNome(nome: string): TPessoa;
begin
 for pessoa in self.pessoas do
  if pessoa.nome = nome then Exit(pessoa);
end;

But here comes the problem, since these two classes are in separate units, it would give a "circular reference" compiler error because I'm using the TSala class in the class TPessoa and the class TPe in the TSala class. How could I fix this without having to call pointer or TObject?

    
asked by anonymous 23.12.2016 / 05:35

1 answer

0

The correct one, in this case, is to create the TSala class as a collection of TPessoa (or, the room class has a field that points to this collection)

You can polite a bit of code if you already make your classes inheriting from the TCollection and TCollectionItem already defined types.

interface   uses System.Classes;

TYPE
TPessoa=Class;{note aqui uma pré-declaração. Permite usar TPessoa em TSala antes de implementa-la}
TSala=Class(TCollection)
public function add:TPessoa;
function pegarPorNome(Nome:String):TPessoa;
property Pessoa(Const Nome:String):TPessoa read pegarPorNome;
constructor create(ItemClass:TCollectionItemClass);
end;

TPessoa=Class(TCollectionItem)
  Nome:String;
  //demais variaveis
  procedure DarQualquerCoisa();
  procedure FazerQualquerCoisa();
end;

implementation

{ TSala }

function TSala.add: TPessoa;
begin
Result := inherited Add as TPessoa;
end;

constructor TSala.create(ItemClass: TCollectionItemClass);
begin
 inherited Create(ItemClass);
end;

function TSala.pegarPorNome(Nome: String): TPessoa;
begin
result := nil;  //se nao encontrar o nome, retorna vazio
for I := 0 to Count-1 do
   begin
     if TPessoa(Items[i]).Nome=Nome then
     begin
     result := Items[i] as TPessoa;
     break;
     end;
   end;
if result = nil then
  showmessage(format('Nome "%s" não encontrado.',Nome));//Nao encontrou esse nome, voce pode emitir um aviso.
end;

{ TPessoa }

procedure TPessoa.DarQualquerCoisa();
begin
;
end;
procedure TPessoa.FazerQualquerCoisa();
begin
;
end;

Finally, how to use this class

procedure TForm1.FormCreate(Sender: TObject);
begin
  Sala1 := TSala.Create;//Sala1 deve ser uma variavel publica
end; 

You can create people in two ways

procedure TForm1.BotaoAddPessoa1Click(Sender: TObject);
var Nova_Pessoa:TPessoa;
begin
 Nova_Pessoa:=Sala.Add;
 Nova_Pessoa.Nome := Edit1.Text;
 //... etc
 Nova_Pessoa.FazerQualquerCoisa();
 Nova_Pessoa.DarQualquerCoisa();
end; 

procedure TForm1.BotaoAddPessoa2Click(Sender: TObject);
begin
//esse é o jeito mais interessante,pois nao precisa declarar variavel
 With Sala.Add do begin
   Nome := Edit1.Text;
//... etc
 FazerQualquerCoisa();
 DarQualquerCoisa();
 end;

end; 
    
27.12.2016 / 02:30