Справочное описание GObject |
---|
Люди часто запутываются пытаясь конструировать собственный объект 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 и конструкционные свойства по умолчанию.