Инстанциируемые классифицируемые типы: объекты
Last updated
Was this helpful?
Last updated
Was this helpful?
Типы которые регистрируются с классом и объявляются инстанциированными очень похожи на объекты object. Хотя s (детали в ) самый известный тип инстанциированного классифицированного типа, другие виды подобных объектов используемых как основа иерархии наследования была внешней разработкой и они все основаны на базовых особенностях описанных ниже.
Например, код показанный ниже демонстрирует как вы должны регистрировать такие базовые типовые объекты в системе типов:
После первого вызова maman_bar_get_type
, тип с именем BarType будет зарегистрирован в системе типов как наследник типа G_TYPE_OBJECT.
Эти ограничения позволяют системе типов удостовериться в том, что каждый экземпляр объекта (идентифицируемый указателем на экземпляр объектной сструктуры) содержит в первом байте указатель на структура класса объекта.
Эти взаимоотношения лучше демонстрируются примером: давайте возьмём объект B который наследуется из объекта A:
C стандартом принято что первое поле C сструктуры начинается в первом байте буфера используемого для содержания структурных полей в памяти. Это значит что первое поле экземпляра объекта B - это первое поле A's которое в свою очередь является первым полем GTypeInstance's которая в свою очередь является g_class, указанным в структуре класса B's.
Благодаря этим условиям, возможно определить тип каждого объекта выполнив:
или, намного быстрее:
Например, если объект B который происходит из A инстанциирован, GType только вызовет instance_init объекта B, в то время как C++ окружение вызовет конструктор объекта A первым, а зтем типового объекта B. Кроме того, C++ код эквивалентный base_init и class_init callback-функциям GType обычно не необходим, потому что C++ не может создавать типовые объекты во время выполнения.
Процесс инстанциирования/завершения можно резюмировать следующим:
Таблица 1. GType Instantiation/Finalization
Время вызова
Вызываемая функция
Параметры функции
типовая функция base_init
В дереве наследования класса из базового типа для целевого типа. base_init вызывается один раз для каждой структуры класса.
функция целевого типа class_init
В структуре класса целевого типа
функция instance_init целевого типа
В экземпляре объекта
функция class_finalize целевого типа
В структуре класса целевого типа
типовая функция base_finalize
В дереве наследования классов из базового типа в целевой тип. base_finalize вызывается один раз для каждой структуры класса.
Каждый объект должен определяться двумя структурами: структурой класса и структурой объекта. Все сструктуры класса должны содержать в качестве первого члена. Все сструктуры объекта должны содержать структуру в качестве первого члена. Декларация этих C типов, взята из gtype.h
, показана ниже:
Инстанциирование этих типов может быть выполнено с помощью :
ищет информационную структуру типа связанную с запрошенным типом. Затем, размер экземпляра и инстанциируемую политику (если поле n_preallocs установлено не в нулевое значение, система типов распределяет экземпляр сструктуры объекта в участок памяти вместо распределения каждого экземпляра) объявленную пользователем используемую для получения буфера содержащего экземпляр объектной сструктуры.
Если это первое инстанциирование создаваемого объекта, система типов должна создать структуру класса: это распределит буфер содержащий структуру объектного класса и инициализирует его. Сначала копируется родительская структура класса поверх этой сструктуры (если нет родителя, инициализируется нулём). Затем вызываются функции base_class_initialization () от самого высшего базового объекта до самого низшего объекта. Объектная функция class_init () вызывается впоследствии, завершая инициализацию сструктуры класса. Наконец, инициализируется интерфейс объекта (позже мы обсудим инициализацию интерфейса более детально). []
Как только система типов получает указатель на инициализированную структуру класса, она устанавливает указатель экземпляра объектного класса в структуру объектного класса и вызывает объектные функции instance_init (), из самого высшего базового типа до самого низшего типа.
Уничтожается объект через очень просто: экземпляр сструктуры возвращается в пул если существует, и если это был последний уничтоженный экземпляр объекта, класс уничтожается.
Уничтожение класса [] (понятие уничтожение иногда описывается как завершение (finalization) в GType) это симметричный процесс инициализации: интерфейсы уничтожаются первыми. Затем, вызывается функция class_finalize (ClassFinalizeFunc). Наконец вызываются функции base_class_finalize () от самого низшего типа до самого высшего базового типа и структура класса освобождается.
Как многие читатели поняли, основы процесса инициализации/завершения очень похожи на парадигму C++ Constructor/Destructor. Практически различия в деталях, хотя это не важно при внешнем сходстве. Обычно, большинству пользователей достаточно знать что C++ constructor (то есть, список методов объекта вызывается в экземпляре объекта один раз для каждого типа иерархии наследования) не существует в GType и должны основываться на предлагаемых особенностях GType. Аналогично, GTypes не имеет механизма деструкции. Ответственность за правильную семантику уничтожения существующего кода GType, лежит на пользователе. (это то что делает GObject. Смотрите )
Первый вызов для целевого типа
инициализация интерфейса, смотрите
Каждый вызов для целевого типа
Последний вызов для целевого типа
уничтожение интерфейса, смотрите