Николай Ряполов Опубликовано 24 марта, 2015 Поделиться Опубликовано 24 марта, 2015 (изменено) Доброго дня. Возник небольшой вопрос при создании классов. Выдержка из кода: //объявление классов TFileInfo = class private ... FSize: Int64; Public ... property Size: Int64 read FSize write FSize; procedure Free; ... end; TListFile<T: TFileInfo> = class(TObjectList<T>) private ... function GetAllSize: Int64; public ... property AllSize: Int64 read GetAllSize; procedure Clear; overload; ... end; // реализация классов ... procedure TFileInfo.Free; begin if Self <> nil then Destroy; end; ... function TListFile<T>.GetAllSize: Int64; var i: integer; begin Result := 0; for i := 0 to Count - 1 do Result := Result + Items[i].Size; end; ... procedure TListFile<T>.Clear; var i: integer; begin for i := 0 to Count - 1 do Items[i].Free; inherited Clear; end; В общем IDE в секции "Structure" выдает ошибки "Undeclared identifier 'Free'('Size') at line №строки в процедуре Clear и GetAllSize Сам код не смотря на выдаваемые ошибки компилируются без Hints и Warnings Ткните меня плиз в мое не совершенство. P.S. Выкрутился таким путем ... function TListFile<T>.GetAllSize: Int64; var tb: T; begin Result:=0; for tb in List do if tb <> nil then Result := Result + tb.Size; end; ... procedure TListFile<T>.Clear; var tb: T; begin for tb in List do if tb <> nil then tb.Free; inherited Clear; end; Подскажите верно ли я поступил? Изменено 24 марта, 2015 пользователем Николай Ряполов Цитата Ссылка на комментарий
Администраторы Brovin Yaroslav Опубликовано 25 марта, 2015 Администраторы Поделиться Опубликовано 25 марта, 2015 Добрый день, Если код компилируется без ошибок и предупреждений, то можно считать, что это баг в Structure. P.S. Однако в вашем коде: Совершенно лишняя реализация метода Clear. Если при создании вашего TObjectList в конуструкторе указать AOwnsObjects = True. То метод Clear из TList<> удалить и распустит ваши элементы. Совершенно лишняя реализация метода Free. Этот метод базовый и присутствует во всех класса, так как он введен на уровне TObject. Цитата Ссылка на комментарий
Николай Ряполов Опубликовано 25 марта, 2015 Автор Поделиться Опубликовано 25 марта, 2015 (изменено) Добрый день, Если код компилируется без ошибок и предупреждений, то можно считать, что это баг в Structure. P.S. Однако в вашем коде: Совершенно лишняя реализация метода Clear. Если при создании вашего TObjectList в конуструкторе указать AOwnsObjects = True. То метод Clear из TList<> удалить и распустит ваши элементы. Совершенно лишняя реализация метода Free. Этот метод базовый и присутствует во всех класса, так как он введен на уровне TObject. Изначально мой класс базировался на TList<T>, но по ряду причин после обработки 500к файлов память забивалась до 150 Мб, и методом TList.Free не освобождалась. Изменил базовый класс на TObjectList , память этим методом TObjectList.Free очищается полностью (100 итераций заполнение - очистка списка). Если я Вас верно понял то в описании класса достаточно описать так: TListFile<T: TFileInfo> = class(TObjectList<T>) private ... AOwnsObjects = True; ... function GetAllSize: Int64; public ... property AllSize: Int64 read GetAllSize; // procedure Clear; overload; //тут можно удалить процедуру ... end; Или требуется сделать так: TListFile<T: TFileInfo> = class(TObjectList<T>) private ... function GetAllSize: Int64; public ... property AllSize: Int64 read GetAllSize; constructor Create; overload; // procedure Clear; overload; //тут можно удалить процедуру ... end; ... constructor TListFile<T>.Create; begin inherited create; AOwnsObjects = True; end; ... Если Вас не затруднит еще один небольшой вопрос. Столкнулся со сравнением двух списков TListObject<T>, где Т: class содержащий информацию о файлах. Сравнивать как списки как: for T in ObjectList1 do if ObjectList2.IndexOf(T)>0 then // тут код сравнения однозначно позволяет установить что именно class 'T' в ObjectList1 точно соответствует class 'T' в ObjectList2. Так как отсутствие class 'Т' из ObjectList1 или малейшее его изменение в списке ObjectList2 однозначно требует проверки на внутреннюю проверку списков методом: var isModif: Boolean; begin ... for T1 in ObjectList1 do begin isModif := False; for T2 in ObjectList2 do begin if T1.Name = T2.Name then begin if (T1.Size <> T2.Size) or (T1.ModDate <> T2.ModDate) then T1.Status := fiModif // const fiModif = $00000001 else T1.Status := fiNoModif; // const fiNoNodif = $00000002 isModif := True; end; if not isModif then T1.Status := fiCreate; // const fiCreate = $00000004 end; end; Если этот же класс реализовать через TDictonary добавив в TKey T1.Name и уже сравнение проводить согласно вхождению файлов в список ObjectList2 скорость сравнения достаточно увеличится или можно пренебречь реализацией? Изменено 25 марта, 2015 пользователем Николай Ряполов Цитата Ссылка на комментарий
Администраторы Brovin Yaroslav Опубликовано 25 марта, 2015 Администраторы Поделиться Опубликовано 25 марта, 2015 TList не освоождает память своих элементов. А вот, если вы хотите, чтобы оъекты-элементы тоже удалялись и есть TObjectList. Но освобождать память под объекты или нет, зависит от значения параметра AOwnedObject при создании списка. Да Цитата Ссылка на комментарий
Николай Ряполов Опубликовано 25 марта, 2015 Автор Поделиться Опубликовано 25 марта, 2015 TList не освобождает память своих элементов. А вот, если вы хотите, чтобы объекты-элементы тоже удалялись и есть TObjectList. Но освобождать память под объекты или нет, зависит от значения параметра AOwnedObject при создании списка. Да Таким образом подытожим выше сказанное: 1. класс создаем таким образом: var LF: TListFile<T>; begin ... LF:= TListFile<T>.Create(True); //так мы говорим что надобно освобождать память автоматически try ... //тут работаем с нашим кодом ... finally LF.Free; //корректно подчищает за собой при установленном флаге AOwnerObject end; end Сам класс для хранения объектов меняем с TObjectList на TDictonary для увеличения производительности при сортировке массивов ввиду уже заложенных в "Словарь" алгоритмов на уровне системы. Спасибо огромное! Цитата Ссылка на комментарий
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.