Delphi. Should I free all elements inside the TObject before releasing?

Please, about this code:

type
  TClient = class(TObject)
  public
    Host: String;
    Queue: TIdThreadSafeStringList;
  end;

var
  Clients: TThreadList;

procedure TMain.FormCreate(Sender: TObject);
const
  Hosts: Array[0..4] of String = (
    'HOST1', 'HOST2', 'HOST3', 'HOST4, 'HOST5'
  );
var
  I: Integer;
  List: TList;
  Client: TClient;
begin
  Clients := TThreadList.Create;
  Clients.Duplicates := dupAccept;
  for I := Low(Hosts) to High(Hosts) do
  begin
    Client := TClient.Create;
    Client.Host := Hosts[I];
    Client.Queue := TIdThreadSafeStringList.Create;
    Clients.Add(Client);
    Client := nil;
  end;
end;

      

I would like to know if its memory release is correct:

procedure TMain.FormDestroy(Sender: TObject);
var
  I: Integer;
  List: TList;
begin
  List := Clients.LockList;
  try
    for I := 0 to List.Count - 1 do
      TClient(List[I]).Free;
  finally
    Clients.UnlockList;
    Clients.Free;
  end;
end;

      

Or it could be like this:

procedure TMain.FormDestroy(Sender: TObject);
var
  I: Integer;
  List: TList;
begin
  List := Clients.LockList;
  try
    for I := 0 to List.Count - 1 do
    begin
      TClient(List[I]).Queue.Free;
      TClient(List[I]).Free;
    end;
  finally
    Clients.UnlockList;
    Clients.Free;
  end;
end;

      

In other words, I would like to know if when the object (TClient) is released, all items (queue) will be released automatically or if I have to do it manually.

Thank!

+3


source to share


1 answer


The queue object must be destroyed when the client object is destroyed. However, the correct way to do this is to make the client class accountable for its members.

type
  TClient = class
  private
    FHost: String;
    FQueue: TIdThreadSafeStringList;
  public
    constructor Create(const Host: string);
    destructor Destroy; override;
  end;
....
constructor TClient.Create(const Host: string);
begin
  inherited Create;
  FQueue := TIdThreadSafeStringList.Create;
  FHost := Host;
end;

destructor TClient.Destroy;
begin
  FQueue.Free;
  inherited;
end;

      



If you do it like this, then it is impossible to instantiate the class and not instantiate its elements. Do it your way, and every time you need to instantiate the class, you have to repeat the code to instantiate the members. It's too easy to make a mistake this way. Which also makes the code harder to read and maintain.

+7


source







All Articles