Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Destroy для вложенных TList.TList


Автор: RinOSpro 9.7.2009, 11:11
Всем привет! Есть 2 класса наседованные от TList,
Код

TAList = class(TList)
end;

TBList = class(TList)
  FAList: TAList;
end;


Вопрос вот в чем, нужно ли в классе TBList, создавать деструктор который делает следующее:
Код

destructor TBList.Destroy;
var
  i: Integer;
begin
  for i := 0 to FAList.Count - 1 do
    FAList[i].Destroy;

  inherited Destroy;
end;

Или этого не обязательно делать, так как это делается автоматом?

Автор: RomanEEP 9.7.2009, 13:08
правильно так:
1)никогда не вызывать Destroy(), а вызывать Free.
2)Каждый объект отвечает за уничтожение только "своих" объектов
Код

destructor TAList.Destroy;
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    TObject(Items[i]).Free;
  inherited;
end;

destructor TBList.Destroy;
var
  i: Integer;
begin
  FAList.Free;
  inherited;
end;



Добавлено через 3 минуты и 20 секунд
ЗЫ: если TAList = class(TObjectList), то деструктор TAList.Destroy будет не нужен

Автор: Alexeis 9.7.2009, 13:13
  Для объектов удобно использовать TObjectList. Он умеет уничтожать объекты.

Автор: RinOSpro 9.7.2009, 16:51
Цитата(Alexeis @  9.7.2009,  13:13 Найти цитируемый пост)
  Для объектов удобно использовать TObjectList


Смотрел код TObjectList, вроде ни каких изменений, на счет Destroy-я объектов в нем нет. даже деструктор не переписан.

Автор: Alexeis 9.7.2009, 17:02
Цитата(RinOSpro @  9.7.2009,  15:51 Найти цитируемый пост)
Смотрел код TObjectList, вроде ни каких изменений, на счет Destroy-я объектов в нем нет. даже деструктор не переписан.


  Плохо смотрел.
Код

constructor Create(AOwnsObjects: Boolean); overload;

Если он создается с флагм true то по уничтожению убьет все объекты, если объекты это тоже TObjectList то для каждого из них вызовется виртуальный деструктор, который уничтожит все внутренние объекты.

Автор: THandle 9.7.2009, 18:09
RinOSpro, деструктор у TObjectList остался старый, от TList. Но реализован метод Notify, реализован следующим образом:

Код

procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
  if OwnsObjects then
    if Action = lnDeleted then
      TObject(Ptr).Free;
  inherited Notify(Ptr, Action);
end;


То есть, если параметр переданный в конструкторе - true и действием является удаление элемента списка, то тогда объект освобождается.
В самой реализации TObjectList метод Notify с lnDeleted не вызывается, а вот в TList такой вызов Notify при удалении элемента предусмотрен.
То есть при "убийстве" экземпляра TObjectList'а происходит следующее(выше TList'а по иерархии не поднимаемся).

TList.Destroy -> TList.Clear -> TList.SetCount(0) -> тут для каждого элемента списка выполняется TList.Delete, а в нем происходит вызов Notify  с lnDeleted -> TObjectList.Notify. Вот тут то и происходит уничтожение объектов находящихся в списке.

Про TObjectList еще можно глянуть статейку:

http://base.vingrad.ru/view/3110-TObjectList

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)