Конструирование объекта

Люди часто запутываются пытаясь конструировать собственный объект GObjects, из-за множества разных способов монтирования в процессе конструирования объекта: трудно сформулировать который является правильным, рекомендованным способом.

Table 4, “g_object_new” показывает что функции обеспечиваемые пользователем вызываются в течение инстанциации объекта и в каком порядке они вызываются. Пользователь ищущий эквивалент простой функции конструктора C++ должен использовать instance_init метод. Он будет вызван после всех родительских функций instance_init. Эта функция не принимает произвольных параметров конструирования (как в C++), но если ваш объект нуждается в произвольных параметрах для завершения инициализации, вы можете использовать свойства конструирования.

Свойства конструкции будут установлены только после всех выполненных функций instance_init. Ссылка объекта не будет возвращена клиенту g_object_new> пока не будут установлены все свойства конструкции.

Также, я рекомендовал бы сначала писать следующий код:

static void maman_bar_init (GTypeInstance *instance, gpointer g_class) { MamanBar *self = (MamanBar *)instance; self->private = g_new0 (MamanBarPrivate, 1); /* Инициализируем все общие и закрытые члены в разумные значения по умолчанию. */ /* Если вам нужно специфичное свойство конструирования для завершения инициализации, * инициализация задерживается пока не установлено свойство. */ }

Убедитесь что вы установили maman_bar_init как типовую функцию instance_init в maman_bar_get_type. Убедитесь что код собирается и выполняется: создайте экземпляр объекта и убедитесь что maman_bar_init вызывается (добавьте в него вызов g_print).

Теперь, если вам нужны специальные свойства конструирования, установите свойства в функцию class_init, отмените установленные и полученные методы и реализуйте получение и установку методов как описано в the section called “Object properties”. Убедитесь что эти свойства используются только конструируя GParamSpec, установив флаговое поле спецификации параметра в значение G_PARAM_CONSTRUCT_ONLY: это поможет GType убедится что свойства не установятся позже снова злонамеренным пользовательским кодом.

static void bar_class_init (MamanBarClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *maman_param_spec; gobject_class->set_property = bar_set_property; gobject_class->get_property = bar_get_property; maman_param_spec = g_param_spec_string ("maman", "Maman construct prop", "Set maman's name", "no-name-set" /* default value */, G_PARAM_CONSTRUCT_ONLY |G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROP_MAMAN, maman_param_spec); }

Если вам это нужно, убедитесь что вы можете собрать и запустить код подобный коду показанному выше. Убедитесь что ваши конструкционные свойства могут правильно устанавливаться в течение конструирования, убедитесь что вы не можете установить их впоследствие и убедитесь что без вызова g_object_new с необходимыми свойствами конструирования, они будут инициализированы значениями по умолчанию.

Я думаю что правильно останавливать выполнение программы если конструкционное свойство установлено в значение по умолчанию. Это позволит вам перехватить клиентский код который не предаёт разумное значение свойствам конструирования. Конечно вы можете не согласиться с этим, но вы должны иметь для этого веские причины.

Некоторые люди иногда нуждаются в конструировании собственных объектов, но только после установки конструкционных свойств. Это возможно благодаря использованию классовому методу конструирования как описано в the section called “Object instanciation”. Однако, я не вижу никаких разумных причин использовать эту особенность. Также, для инициализации вашего экземпляра объекта, используйте функцию base_init и конструкционные свойства по умолчанию.