Создание экземпляров объектов
Экземпляр объекта создается посредством описание переменной или константы объектного типа или путем применения стандартной процедуры New к переменной типа указатель на объектный тип. Ре- зультирующий объект называется экземпляром объектного типа.
var F: TField; Z: TZipField; FP: PField; ZP: PZipField;
С учетом этих описание переменных F является экземпляром TField, а Z - экземпляром TZipField. Аналогично, после применения New к FP и ZP, FP будет указывать на экземпляр TField, а ZP - на экземпляр TZipField.
Если объектный тип содержит виртуальные методы, то экземпля- ры этого объектного типа должны инициализироваться посредством вызова конструктора перед вызовом любого виртуального метода. Ни- же приведен пример:
var S: StrField; begin S.Init (1, 1, 25, 'Первое имя'); S.Put ('Френк'); S.Display; ... S.Done; end;
Если S.Init не вызывался, то вызов S.Display приведет к неу- дачному завершению данного примера.
Присваивание экземпляра объектного типа не подразумевает инициализации экземпляра.
Объект инициализируется кодом, генерируемым компилятором, который выполняется между вызовом конструктора, и когда выполне- ние фактически достигает первого оператора в блоке кода конструк- тора.
Если экземпляр объекта не инициализируется, и проверка диа- пазона включена (директивой {$R+}), то первый вызов виртуального метода экземпляра объекта дает ошибку этапа выполнения. Если про- верка диапазона выключена (директивой {$R-}), то первый виртуаль- ного метода неинициализированного объекта может привести к неп- редсказуемому поведению.
Правило обязательной инициализации применимо также к экземп- лярам, которые являются компонентами структурных типов. Например:
var Comment: array [1..5] of TStrField; I: integer; begin for I := 1 to 5 do Comment [I].Init (1, I + 10, 40, 'первое_имя'); . . . for I := 1 to 5 do Comment [I].Done; end;
Для динамических экземпляров инициализация, как правило, связана с размещением, а очистка - с удалением, что достигается благодаря расширенному синтаксису стандартных процедур New и Dispose. Например:
var SP: StrFieldPtr; begin New (SP, Init (1, 1, 25, 'первое_имя'); SP^.Put ('Френк'); SP^.Display; . . . Dispose (SP, Done); end;
Указатель на объектный тип является совместимым по присваи- ванию с указателем на любой родительский объектный тип, поэтому во время выполнения программы указатель на объектный тип может указывать на экземпляр этого типа или на экземпляр любого дочер- него типа.
Например, указатель типа ZipFieldPtr может присваиваться указателям типа PZipField, PNumField и PField, а во время выпол- нения программы указатель типа PField может либо иметь значение nil, либо указывать на экземпляр TField, TNumField или TZipField, или на любой экземпляр дочернего по отношению к TField типа.
Эти правила совместимости указателей по присваиванию приме- нимы также к параметрам-переменным объектного типа. Например, ме- тоду TField.Copy могут быть переданы экземпляры типов TField, TStrField, TNumField, TZipField или любые другие экземпляры до- чернего от TField типа.