Создание и уничтожение объектов
В Object Pascal экземпляры объектов могут быть только динамическими.
type TMyObject = class(TObject) MyField: Integer; function MyMethod: Integer; end; |
var AMyObject: TMyObject;
В этом примере описан класс TMyObject, содержащий поле MyField и метод MyMethod.
Это означает, что в приведенном выше фрагменте переменная AMyObject на самом деле является указателем, содержащим адрес объекта.
Объект "появляется на свет" в результате вызова специального метода, который инициализирует объект – конструктора. Созданный экземпляр уничтожается другим методом – деструктором:
AMyObject := TMyObject.Create; { действия с созданным объектом } ... AMyObject.Destroy; |
Здесь объекта еще нет, но обратите внимание, что вызывается метод TMyObject.Create, а не AMyObject.Create. Есть такие методы (в том числе конструктор), которые успешно работают до (или даже без) создания объекта.
В Object Pascal конструкторов у класса может быть несколько. Общепринято называть конструктор create. Типичное название деструктора – Destroy.
type TMyObject = class(TObject) MyField: Integer; Constructor Create; Destructor Destroy; Function MyMethod: Integer; end; |
Для уничтожения экземпляра объекта рекомендуется использовать метод Free, который первоначально проверяет указатель (не равен ли он Nil) и только затем вызывает Destroy:
AMyObject.Free ; |
До передачи управления телу конструктора происходит создание объекта – под него отводится память, значения всех полей обнуляются. Далее выполняется код конструктора, написанный программистом для инициализации экземпляров данного класса. Таким образом, хотя синтаксис конструктора схож с вызовом процедуры (не определено возвращаемое значение), но на самом деле конструктор – это функция, возвращающая созданный и инициализированный объект.
Динамически создаваемые компоненты - это компоненты, место в памяти под которые выделяется по мере необходимости в процессе работы приложения. Этим они и отличаются от компонентов, которые помещаются на Форму при проектировании приложения. Возможность создавать компоненты динамически это очень большое удобство для программиста. Например, можно создавать в цикле сразу много однотипных компонентов, формируя из них массив, которым в дальнейшем очень просто управлять.
Прежде всего, для появления динамически создаваемого компонента нужно выделить под него место в памяти. Выделением места в памяти компьютера под любой компонент занимается конструктор типа объекта этого компонента - метод Create. Для этого сначала нужно описать переменную нужного типа, а затем для выделения памяти воспользоваться методом Create. Метод Create имеет параметр Owner, определяющий так называемого "владельца" для создаваемого компонента.
Хотя на самом деле владелец нужен не для создания, а для уничтожения компонента. То есть, при уничтожении компонента-владельца происходит автоматическое уничтожение всех компонентов, у которых он указан в качестве владельца.
При обычной установке компонента из палитры система делает владельцем этого компонента Форму. Проще всего поступать так же. Однако можно указать в качестве владельца сам этот компонент, воспользовавшись в качестве параметра ключевым словом Self.
. Когда компонент создан, то есть место в памяти под него выделено, можно задавать значения параметрам этого объекта. Прежде всего, это ещё один компонент, так называемый "родитель". Компонент-родитель будет отвечать за отрисовку нашего динамически создаваемого компонента. Это значит, что новый компонент появится в границах компонента-родителя.
Если компонент-владелец имеет тип TComponent, то есть может быть любым компонентом, то компонент-родитель уже имеет тип TWinControl. То есть это должен быть "оконный" компонент, умеющий принимать и обрабатывать сообщения от системы Windows. Это необходимо, так как компонент должен находиться в некоторой иерархии компонентов, принимающих и передающих сообщения от системы Windows.
Естественно, компонент не может быть родителем для самого себя. Имя компонента-родителя просто присваивается свойству Parent создаваемого динамически компонента.
Давайте для примера динамически создадим многострочный редактор, компонент Memo. Пусть он появляется на Форме по нажатию кнопки:
procedure TForm1.Button1Click(Sender: TObject); var Memo: TMemo; begin Memo:=TMemo.Create(Form1); Memo.Parent:=Form1; Memo.Left:=50; Memo.Top:=50; Memo.Width:=250; Memo.Height:=100; Memo.Text:='Я появился!'; end; |
К данному компоненту можно обращаться как по этому имени, так и с указанием переменной, с помощью которой он был создан: Memo. Естественно, в последнем случае переменная должна быть глобальной.
Для уничтожения компонента есть простой метод: Free. Все ресурсы, выделенные для функционирования компонента, будут освобождены. Останется только созданная переменная, указывающая на уже несуществующий в памяти объект. Её тоже неплохо бы уничтожить. Это делается присвоением переменной значения nil. Есть процедура, выполняющая оба эти действия, уничтожение и объекта и переменной: FreeAndNil:
FreeAndNil(Component);
Для примера создадим новый класс, измененный TButton, в котором изменим значение по умолчанию свойства ShowHint на True и добавим новое свойство - счетчик нажатий на кнопку. Исходный текст выглядит так:
unit New_btn;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;
type
TMyButton = class(TButton)
private
{ Private declarations }
FClickCount : Longint;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner : TComponent); override;
procedure Click; override;
property ClickCount : Longint read FClickCount write
FClickCount;
published
{ Published declarations }
end;
procedure Register;
implementation
constructor TMyButton.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
ShowHint:=True;
FClickCount:=0;
end;
procedure TMyButton.Click;
begin
Inc(FClickCount);
inherited Click;
end;
procedure Register;
begin
RegisterComponents('Samples', [TMyButton]);
end;
end.
Дата добавления: 2016-07-05; просмотров: 2551;