Внутренняя структура объекта.
type TFirstClass = class (TObject) FMyField1: integer; FMyField2: longint; procedure StatMethod; procedure VirtMethod1; virtual; procedure VirtMethod2; virtual; procedure DynaMethod1; dynamic; procedure DynaMethod2; dynamic; end; TSecondClass = class (TFirstClass) procedure StatMethod; procedure VirtMethod1; virtual; procedure DynaMethod1; dynamic; end; var Odj1: TFirstClass; Obj2: TSecondClass; В памяти это будет выглядеть так:
Первое поле каждого из объектов содержит указатель на его класс. Класс как структура состоит из двух частей. С адреса, на который ссылается???? VMT. В этой таблице содержатся адреса всех виртуальных методов класса, как описанных в данном классе, так и в унаследованных им от класса-предка. Непосредственно перед VMT расположена область памяти, в которой хранится служебная информация о классе, т.е. его имя, размер, занимаемый в памяти экземпляром данного класса, указатели на класс-предок и другая информация. Одно из полей этой таблицы содержит указатель на таблицу динамических методов объекта DMT. DMT имеет следующий формат: в первом ее слове хранится число динамических методов объекта, во втором слове содержится индекс первого метода. Нумерация начинается с -1 и идет по убывающей. Непосредственно за индексами хранятся адреса динамических методов. В этой таблице хранятся только те методы, которые описаны в данном классе. Т.о. экономится память при использовании динамических методов. Непосредственно в VMT содержатся??? SYSTEM.PAS vmtSelfPlr = -76 – используется при использовании классов динамических методов vmtIntfTable = -74 vmtAutoTable = -68 – используется при работе с объектами с интерфейсом COM vmtInitTable = -64 – используется при работе с объектами с интерфейсом COM vmtTypeInfo = -60 vmtFieldTable = -56 vmtMetodTable = -48 vmtDynamicTable = -48 vmtClassName = -44 vmtInstanceSize = -40 vmtSafeCallException = -32 – используется при работе с объектами с интерфейсом COM
vmtAfterConstruction = -28 vmtBeforeDestruction = -24 vmtDispath = -20 – используется при использовании классов динамических методов vmtDefaultHandler = -16 – используется при использовании классов динамических методов vmtNewInstance = -12 – используется в создании и уничтожении экземпляров класса vmtFreeInstance = -8 – используется в создании и уничтожении экземпляров класса vmtDestroy = -4 – используется в создании и уничтожении экземпляров класса Остальные поля этой таблицы доступны через методы класса TObject. Содержимое этой таблицы является важным и может в программе использоваться неявно.
Использование операторов is и as. В языке Object Pascal существуют два оператора is и as, которые неявно обращаются к этой таблице. Оператор is предназначен для проверки совместимости по присваиванию объекта из заданного класса. Конструкция вида: AnObject is TSomeType будет возвращать значение истина, если объект TOdject является совместимым по присваиванию с классом TSomeType, т.е. объектом Object является либо экземпляр данного класса либо экземпляр одного из его дочерних класса. Определенная проверка на совместимость выполняется на стадии компиляции программы???. Оператор as был введен в язык Object Pascal для обеспечения возможности приведения объектных типов. С его помощью экземпляру класса можно присвоить другой совместимый с ним по присваиванию класс. with AObject as TAnyObject do … От стандартного способа приведения классов с помощью конструкции TAnyObject(AObject) использование оператора as отличается проверкой на наличие совместимости по присваиванию в выполняемой во время исполнения оператора as. Если делается попытка приведения несовместимых типов, то будет выработана исключительная ситуация EInvalidCast. После исполнения оператора as объект сохраняет свой тип. Однако из него становится доступны методы и свойства, соответствующие приведенному классу. Особенно полезно использование оператора as в методах обработчиках событий. Для обеспечения совместимости в 99% случаях объект-источник события Sender: Tobject принадлежит классу TObject. Хотя в тех же 99% случаях объектом-источником события выступает форма или один из ее компонентов. Для того, чтобы использовать свойства и методы источника события и применяют оператор as.
(Sender as TControl).Caption:= ‘abcd’
Указатели на класс и методы класса. Служебная информация о классе создается и размещается в памяти на этапе компиляции. Получить доступ к этой информации, не прибегая к методам класса, можно, описав специальный указатель, который называется указателем на класс или указателем на объектный тип (class reference). Этот указатель описывается с помощью зарезервированных слов class of. При работе с указателями на класс действует правило приведения объектных типов. Указателям на родительский класс можно присвоить значение любого из указателей на его классы-потомки. Обратное неверно. type TFirst = class (TObject) … end; TSecond = class (TFirst) … end; TFirstClass = class of TFirst TSecondClass = class of Second var AFirst: TFirstClass ASecond: TSecondClass begin AFirst:= TSecond; //допустимо ASecond:= TFirst; //недопустимо end С понятием указателя на класс связано понятие методов класса. Это такие методы, которые могут вызываться без создания экземпляра класса. Перед их использованием надо указывать не имя объекта, а имя класса. Описываются эти методы с помощью указания ключевого слова class. type TMyObject = class (TObject) class function GetString: String end; var AMyObject: TMyObject; AString: String; begin AString:= TMyObject.GetString; AMyObject:= TMyObject.Create; AString:= AMyObject.AString; end; Естественно методы класса не могут обращаться к содержимому полей класса.??????? Методы класса используются для получения служебной информации о классе с тем, чтобы не приходилось раскрывать внутреннюю структуру класса. class function TObjectClassNameIs (const Name: String): Boolean – возвращает значение истина, если имя класса будет совпадать с заданным именем. class function TObject.ClassParent: TClass – возвращает указатель на родительский класс. class function TObject.Info: Pointer – возвращает указатель на служебную информацию о классе. class function TObject.MethodAddres (const Name: Short String): Pointer – возвращает адрес метода по его имени. class function TObject.MethodName (Addres: Pointer): Short String – возвращает имя метода по его адресу. Применяется только для опубликованных методов.
Начиная с Delphi 4 появились еще 2 метода: AfterConstructor, BeforeDestruction – они вызываются либо сразу после создания объекта, либо перед его уничтожением.
Иерархия базовых классов. Все классы библиотеки VCL происходят от группы базовых классов, лежащих в основе иерархии. Наиболее общим предком для всех компонентов является класс TObject, инкапсулирующий простейший объект. При наследовании классы-потомки могут наследовать поля, свойства и методы родительских классов. В классах-потомках можно добавлять новые поля, свойства и методы, но нельзя удалять унаследованные от родительских классов. Поэтому иерархия базовых классов продумана очень тщательно, т.к. на ее основе реализовано все множество компонентов. Особое место занимают классы TComponent и TControl – все элементы управления.
Благодаря механизму наследования потомки базового класса могут общаться между собой, работают в среде разработки, взаимодействуя с инспектором объектов и палитрой инструментов. Воспринимаются операционной системой как окна и элементы управления. В основе иерархии лежит класс TObject, который обеспечивает все классы базовыми механизмами для работы с объектами. В частности от него классы наследуют методы создания и уничтожения экземпляров класса. Благодаря возможностям TPersistent объекты получают возможность взаимодействовать друг с другом. Класс TComponent является важнейшим для всех компонентов. От него можно порождать любые не визуальные компоненты. Благодаря возможностям этого класса обеспечивается взаимодействие объекта со средой разработки, главным образом с инспектором объектов и палитрой инструментов. Класс TControl обеспечивает функционирование визуальных компонентов. Класс TWinControl расширяет возможности класса TControl. На его основе создаются оконные элементы управления. Благодаря возможностям этого класса обеспечивается взаимодействие с графическим интерфейсом пользователя GUI (Graphic User Interface). Класс TCustomControl предназначен для работы со специальным объектом, называемым Канва, который предназначен для рисования графики.
Класс TPersistent. В иерархии?? TPersistent (устойчивый, постоянный)????? procedure assign (Source: TPersistent) С помощью этого метода можно скопировать содержимое одного объекта с именем Source в другой объект с именем Self, т.е. в объект, вызвавший данный метод. При этом объект-получатель остается самим собой, чего нельзя достигнуть применяя просто конструкцию присваивания переменных объектного типа (FirstObject = SecondObject). При применении такой конструкции указатель на одну область адресного пространства, содержащего объект, будет просто заменен указателем на другую область памяти, содержащую другой объект. Метод assign позволяет продублировать объект, т.е. присвоить значения всех его свойств другому объекту при этом объект не обязан быть одного класса и даже не обязан находиться в отношениях родитель-потомок. Метод assign допускает полиморфное присвоение. ClipBoard.Assign (Picture) – это означает, что в буфер обмена Windows, т.е. объект ClipBoard, помещается картинка с именем Picture. В буфер обмена можно помещать растровые картинки текст, мультимедийные данные и многие другие объекты. Для примера перепишем метод assign класса TClipBoard, так чтобы он выполнял???? procedure TClipBoard.Assign (Source: TPersistent) begin if Source is TPicture then Picture.Assign (TPicture(Source)) else if Source is TGraphic then Graphic.Assign (TGraphic(Source)) else inherited Assign (Source); end; Следующий метод класса TPersistent предназначен для организации взаимодействия его потомков со средой приложения. function GetNamePath: string; dynamic. Возвращает имя объекта для инспекторов объектов. Класс TPersistent никогда не используется напрямую. От него должны быть порождены потомки, умеющие передавать значение другим объектам, но при этом не быть компонентом.
Класс TComponent. Сдедующим по иерархии идет класс TComponent. Этот класс является основой для компонентов из VCL. Непосредственно от него можно порождать любые невизуальные компоненты. В своем составе этот класс содержит основные механизмы, обеспечивающие функционирование любых компонентов. В этом классе впервые появляются свойства видимые из инспектора объектов. property Name: TComponentName; (тип TComponentName представляет собой простую строку). Обозначает имя компонента, служащее для его идентификации в программе. property Tag: Longint – это свойство может быть использовано разработчиком по его усмотрению, в частности для более удобной идентификации компонентов. В описании конструктора класса содержится описание лишь на 1 объект. constructor Create (AOwner: TComponent) AOwner – объект, который при создании вызывает конструкторы всех объектов, владельцем которых он является, а при уничтожении их деструкторы. Т.о., разместив компоненты на форме, можно не беспокоиться о его создании и уничтожении в приложении. Все свойства и связи компонента с другими компонентами сохраняются в файле формы, а при запуске приложения вновь создаются. Деструктор класса TComponent
destructor Destroy уничтожает все объекты, владельцем которых является данный компонент, путем вызова их деструкторов, а затем вычеркивает себя из списка владельцев компонентов. Для реализации описанной иерархии компонентов в классе TComponent введены механизмы учета и управления компонентами, владельцем которых выступает данный компонент. Свойства и методы используемые для учета и управления компонентами: property Components[Index: Integer]: TComponent – содержится индексированный список всех компонентов, владельцем которых является данный компонент. property ComponentCount: Integer – содержится число компонентов подчиненных данному. property Owner: TComponent – содержится имя владельца компонента. property ComponentIndex: Integer – номер компонента в индексно-номерованном списке компонента-владельца. procedure InsertComponent (AComponent: TComponent) – этот метод вставляет компонент с именем AComponent в индексный список компонента-владельца. procedure R (AComponent: TComponent) – этот метод удаляет компонент с именем AComponent из индексного списка владельца. procedure FindComponent (AName: String) – этот метод осуществляет поиск компонента по его имени. procedure DestroyComponent – уничтожает все дочерние компоненты компонента владельца. Очень важное свойство, которое позволяет получить состояние компонента в текущий момент времени: type TComponentState = Set of (csLoading, csReading, csWriting, csDestroying, csDesigning, csAncestor, csUpDating, csFixups) var ComponentState = TComponentState; Состояние компонента может измениться в результате получения сообщения, выполнения действий пользователя и т.д. Параметры, характеризующие … · csLoading – компонент загружается из потока. · csReading – чтение значений свойств компонента из потока. · csWriting – происходит запись значений свойств компонента в поток. · csDestroying – уничтожение компонента. · csDesigning – состояние разработки, т.е. устанавливается во время… · csAncestor – состояние устанавливается, когда компонент переносится на форму. Чтобы состояние установилось необходимо, чтобы было установлено состояние csDesigning. · csUpDating – при изменении значений свойств компонента и отображении их на форме владельца. Чтобы это состояние установилось необходимо установить состояние csAncestor. · csFixups – устанавливается, если компонент имеет связи с компонентами из другой формы, которая еще не загружена в среду разработки. Для реализации механизма действия Actions в классе TComponent имеется динамический метод function ExecutAction (Action: TBasicAction): Boolean; dynamic Этот метод автоматически вызывается при необходимостивыполнить для какого-либо компонента некоторую акцию. На уровне класса TComponent также встроена поддержка интерфейсов COM-объектов. Обратившись к свойству property ComObject: IUnKnown можно получить доступ к методам этих интерфейсов.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|