Инициализировать GObject с параметрами, которые не являются свойствами GObject? - PullRequest
3 голосов
/ 15 октября 2011

У меня есть GObject "A", который создает экземпляр другого GObject "B" в своем конструкторе.

Объекту "B" необходимо передать несколько свойств только для строительства. Теперь при создании экземпляра объекта «A» я хочу разрешить передачу значений для этих свойств через конструктор объекта «A» в конструктор объекта «B».

Единственный способ сделать это - создать идентичные свойства для объекта "A" и передать их значения конструктору "B". Эти свойства больше не будут иметь никакого значения для «А», так что это похоже на пометку.

Есть ли лучший способ сделать то, что я хочу?

Ответы [ 2 ]

1 голос
/ 15 октября 2011
  • Имеет A наследование от B.Тогда A автоматически получит все свойства B.
  • Не используйте свойства в A, а вместо этого передайте свойства B (или, что еще лучше, уже построенный *)1010 * объект) в качестве параметров для конструктора A.
  • Задержка построения B до A может выяснить, как ее настроить B.Добавьте приватный флаг к A, b_initialized или что-то, что говорит вам, является ли действительным внутренний указатель A на B.

Еще несколько уточнений по второму предложению:Материал

A создается в функции a_init(), которая предоставляется макросом G_DEFINE_TYPE().Но это не то, как вы получаете экземпляр A.Обычно пишут функцию, которая является частью общедоступного интерфейса A, например:

A *a_new() 
{
    return (A *)g_object_new(TYPE_A, NULL);
}

Вы можете легко расширить это, чтобы включить другие параметры:

A *a_new(int b_param_1, int b_param_2)
{
    A *a = (A *)g_object_new(TYPE_A, NULL);
    a->priv->b = b_new(b_param_1, b_param_2);
    return a;
}

Недостатком этого является то, что ваш A объект остается в недопустимом состоянии (то есть без B), если вы создаете его с использованием g_object_new, например, если вы пытаетесь построить его из файла GtkBuilder.Если это проблема, я все равно настоятельно рекомендую рефакторинг.

0 голосов
/ 21 сентября 2016

Используйте внедрение зависимостей , передайте уже инициализированный объект типа B в конструктор A.

Таким образом, клиент, использующий ваш класс, может решить, следует липередать различные типы B s (если есть смысл, вы даже можете использовать интерфейс вместо класса в качестве типа B, написание кода для интерфейсов обычно лучше, чем написание кода для реализаций).

Вывод A из B имеет смысл, только если он действительно является специализацией родительского класса.

Из вопроса неясно, имеет ли смысл деривация, но часто используется слишком часто.метод для композиции.

...