Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


TObjectList

Поиск:
TObjectList

TObjectList предназначен для динамического хранения потомков класса TObject.
У него есть множество преимуществ: контроль за памятью, возможность сортировки, отслеживания пустых элементов.
Он имеет очень хорошие возможности по работе с объектами.
Все это делает TObjectList наиболее удобным средством для хранения объектов и управления ими.

Рассмотрим методы этого класса.

Методы класса TObjectList:
Create
Код

constructor Create(AOwnsObjects: Boolean);

Создает новый ObjectList.
Параметр AOwnsObjects определяет, как будут уничтожаться объекты в случае их удаления из списка.
Если AOwnsObjects установлен в true, это будет происходить автоматически,
если false – надо будет делать все самостоятельно.
По умолчанию он равен true.

Add
Код

function Add(AObject: TObject): Integer;

Добавляет новый объект в конец списка, увеличивает свойство Count на единицу и,
если необходимо, выделяет память, увеличивая значение Capacity (мы рассмотрим позже это свойство).

Extract
Код

function Extract(Item: TObject): TObject;

Удаляет объект из списка, не уничтожая его (даже если OwnsObjects равен true!).
Item – это имя удаляемого объекта.
Индекс элементов, которые стояли после удаленного, автоматически уменьшается на единицу, а также уменьшается свойство Count.
Функция возвращает только что удаленный из списка объект.

Insert
Код

procedure Insert(Index: Integer; AObject: TObject);

Вставляет новый объект на указанную позицию, сдвигая стоящий на этом месте элемент, а также все следующие за ним элементы.
Index – позиция, на которую вставляется объект, указанный в AObject.
При необходимости для нового элемента выделяется память.

First
Код

function First: TObject;

Возвращает первый элемент списка.

Last
Код

function Last: TObject;

Возвращает последний элемент списка.

FindInstanceOf
Код

function FindInstanceOf(AClass: TClass; AExact: Boolean = True; AStartAt: Integer = 0): Integer;

Возвращает индекс первого найденного объекта, который относится к классу, указанному в AClass.
Поиск начинается с индекса, указанного в AStartAt.
Если AExact равен false, то будет производиться поиск не только объектов класса AClass, но и его потомков.

IndexOf
Код

function IndexOf(AObject: TObject): Integer;

Возвращает индекс объекта AObject в списке.


Методы класса TList:

Remove
Код

function Remove(AObject: TObject): Integer;

Единственное отличие от Extract состоит в том, что удаленный элемент уничтожается, если OwnsObjects равен true.
Возвращает индекс элемента до того, как он был удален.

Delete
Код

procedure Delete(Index: Integer);

Отличается от Extract тем, что в качестве параметра передается не имя, а индекс.
Если OwnsObjects равен true, то сразу же вызывается метод Free.
Чтобы вручную освободить память, которая использовалась для хранения объекта, достаточно уменьшить параметр Capacity.
Индексы элементов и Count изменяются так же, как и у Extract.

Assign
Код

procedure Assign(ListA: TList; AOperator: TListAssignOp = laCopy; ListB: TList = nil);

Копирует элементы из одного списка в другой.
Если ListB=nil, то элементы перемещаются из ListA в данный список, при этом используется оператор, указанный в AOperator.
Если ListB указан, то сначала все элементы данного списка копируются в ListA, а затем объекты из ListB перемещаются в данный список,
при этом используется оператор, указанный в AOperator.
Теперь немного об этих операторах:
laAnd – удаляет из списка-получателя все элементы, которых нет в исходном списке.
laCopy – очищает список-получатель и полностью копирует в него исходный список (по умолчанию выбран этот вариант).
laDestUnique – удаляет из списка-получателя все элементы, которые присутствуют в исходном списке.
laOr – добавляет из исходного списка все элементы, которых нет в списке-получателе.
laSrcUnique – копирует из исходного списка все элементы, которых нет в списке-получателе, предварительно очистив список-получатель.
laXor – удаляет из списка-получателя те элементы, которые есть в исходном списке,
затем добавляет туда из исходного списка элементы,
которых изначально не было в списке-получателе.

Pack
Код

procedure Pack;

Удаляет из списка все элементы, равные nil, при этом Count присваивается значение,
равное количеству используемых элементов (то есть не равных nil).
Память, занимаемая ими, не освобождается. Чтобы очистить ее, надо произвести такое действие:

Код

ObjectList.Capacity := ObjectList.Count;


Expand
Код

function Expand: TList;


Увеличивает значение параметра Capacity (т.е. увеличивает вместимость).
Работает только в том случае, если количество элементов в списке равно вместимости листа.
Если значение Capacity больше, чем 8, Expand увеличивает вместимость списка до 16.
Если значение Capacity больше 4, но меньше 9, Capacity увеличивается до 8.
Если Capacity меньше 4, вместимость увеличивается до 4.
Функция возвращает сам ObjectList.

Clear
Код

procedure Clear;

Этот метод удаляет все элементы из списка, освобождает память,
используемую для хранения объектов, а также присваивает свойству Capacity значение 0.

Exchange
Код

procedure Exchange(Index1, Index2: Integer);

Меняет местами два элемента списка.

Move
Код

procedure Move(CurIndex, NewIndex: Integer);

Перемещает элемент списка на другую позицию.
CurIndex – текущий номер объекта, NewIndex – его новый номер.

Sort
Код

procedure Sort(Compare: TListSortCompare);


Метод сортирует элементы списка.
В функции TListSortCompare должно быть указано, как следует располагать объекты в списке:

Код

TListSortCompare = function (Item1, Item2: Pointer): Integer;


Пример:
При нажатии на Button1 кнопки, которые перечислены  списке,
будут расположены в алфавитном порядке (сравнение будет идти по параметру Caption):

Код

function CompareObjectName(Btn1, Btn2: TButton): integer;
begin
Result := CompareText(Btn1.Caption, Btn2.Caption);  //функция CompareText – стандартная, сравнивает две строки.
//Если первая строка больше, возвращает значение больше 0,
//если равны – возвращает 0, если вторая больше, то возвращает отрицательное число
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ObjList.Sort(@CompareObjectName);
end;



А теперь немного о свойствах TObjectList:
OwnsObjects
Код

property OwnsObjects: Boolean;

Позволяет TObjectList самостоятельно контролировать память, занимаемую объектами.
Если его значение равно true, то:

  • Вызов методов Delete или Remove уничтожает объект, который был удален из списка





  • Процедура Clear не только удаляет объекты из списка, но и уничтожает их





  • Вызов деструктора уничтожает все элементы списка, а не только сам ObjectList





  • При добавлении нового объекта на определенную позицию уничтожается находившийся там ранее объект

Однако метод Extract будет в любом случае удалять объект из списка без его уничтожения.

Capacity
Код

property Capacity: Integer;

Определяет размер массива, в котором хранятся объекты.
Если при добавлении нового элемента окажется, что список заполнен, то Capacity будет увеличено.
Count
Код

property Count: Integer;

Показывает, сколько элементов списка используется в данный момент.
Если увеличить значение Count, то в список будут добавлены пустые указатели (nil).
При его уменьшении будет удалено необходимое число записей.

Items

Код

property Items[Index: Integer]: TObject;  default;


С помощью Items можно получить доступ к объектам, хранящимся в списке.
Items является свойством по умолчанию, а значит следующие две строки равносильны:

Код

ObjectList.Items[1] := Button1;
ObjectList[1] := Button1;






Пора перейти от теории к практике.
Вот несколько примеров, которые демонстрируют область применения TObjectList.
Пример 1.
Работа с динамически созданными объектами (а именно с TEdit).
Нужно создать свой собственный класс, который будет потомком TObjectList.
Для этого требуется перекрыть методы SetItems и GetItems.
В интерфейсной части модуля, после слова type, пропишите такой код:

Код

EditList = class(TObjectList)
  public
    property Items[Index: Integer]: TEdit read GetItems write SetItems; default;  
//чтение элементов списка будет происходить через метод GetItems,
//а запись - через SetItems
  end;

и нажмите Ctrl+Shift+C. В конце модуля сгенерируется:

Код


function TEditList.GetItems(Index: Integer): TEdit;
begin

end;

procedure TEditList.SetItems(Index: Integer; const Value: TEdit);
begin

end;


В GetItems вставьте строку
Код

Result := TEdit(inherited GetItem(Index));

В SetItems:
Код

inherited SetItem(Index, Value);

Теперь у нас есть класс, предназначенный для хранения TEdit’ов.


Приступим к работе с этим классом.

Код

var EditList: TObjectList;  //глобальная переменная

procedure TForm1.Button1Click(Sender: TObject);
var Edit: TEdit;
    i: integer;
begin
EditList := TObjectList.Create(true);
for i := 1 to 20 do
begin
  Edit := TEdit.Create(nil);
  Edit.Parent := Form1;
  Edit.Top := 40 + 25*i;
  Edit.Left := 120;
  Edit.Name := 'MyEdit'+IntToStr(i);    
  Edit.Text := '';
  EditList.Add(Edit);
end;
end;


Как вариант:

Код

procedure TForm1.Button1Click(Sender: TObject);
var Edit: TEdit;
    i: integer;
begin
EditList := TObjectList.Create(true);
for i := 1 to 3 do
begin
  Edit := TEdit.Create(nil);
  Edit.Parent := Form1;
  Edit.Top := 40 + 25*i;
  Edit.Left := 120;
  case i of
    1: Edit.Name := 'Surname';
    2: Edit.Name := 'Name';
    3: Edit.Name := 'Adress';
  end;
  Edit.Text := '';
  EditList.Add(Edit);
end;
end;



Теперь можно работать с Edit’ами так же, как с элементами массива:
Код

EditList[2].Text := '111';


При использовании второго способа индекс объекта знать не обязательно, нужно только его имя.
Для удобства напишем функцию, которая находит Edit по его имени:

Код

function FindEdit(Name: string; List: TEditList): integer;
var i: integer;
begin
for i := 0 to List.Count-1 do
  if List[i].Name = Name then
    Result := i;
end;



Пример 2.
Выравнивание компонентов.
Представим такую ситуацию: получилось, что динамически созданные компоненты на форме расположены как попало, и их надо выровнять.
С помощью TObjectList очень легко решить эту задачу.
Этот код выравнивает на форме TEdit’ы (использован класс TEditList из предыдущего примера):
Код

function CompareObjectName(Obj1, Obj2: TEdit): integer;
begin
Result := CompareText(Obj1.Name, Obj2.Name);
end;

procedure TForm1.Button11Click(Sender: TObject);
var i: integer;
begin
EditList := TEditList.Create(true);
EditList.Add(Edit1);
EditList.Add(Edit2);
EditList.Add(Edit3);
EditList.Add(Edit4);
EditList.Add(Edit5);
EditList.Sort(@CompareObjectName);
for i := 0 to EditList.Count-1 do
  begin
  EditList[i].Left := 120;
  EditList[i].Top := 60+i*30;
  end;
end;



Пример 3.
Работа с данными.
В этом примере я рассмотрю создание некого подобия адресной книги.
Для начала создадим класс, который нужен для хранения данных об отдельном человеке:

Код

  TInfo = class
    Surname: string;
    Name: string;
    Adress: string;
    Age: integer;
    Phone: string;
    Email: string;
  end;



Осталось создать класс, который будет потомком TObjectList и будет предназначен для хранения данных типа TInfo:

Код

  TAdressBook = class(TObjectList)
  public
    property Items[Index: Integer]: TInfo read GetItems write SetItems; default;
  end;


Нажмите Ctrl+Shift+C. Появятся два метода: GetItems и SetItems. Вот их код:

Код

function TAdressBook.GetItems(Index: Integer): TInfo;
begin
Result := TInfo(inherited GetItem(Index));
end;

procedure TAdressBook.SetItems(Index: Integer; const Value: TInfo);
begin
inherited SetItem(Index, Value);
end;


Программа готова!

© Sunr1se






Просмотров: 31516

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную