Инициализировать GObject с параметрами, которые не являются свойствами GObject?

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

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

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

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


person user996839    schedule 15.10.2011    source источник


Ответы (2)


  • Наследовать A от B. Тогда A автоматически получает все свойства B.
  • Не используйте свойства в A, вместо этого передайте свойства B (или, что еще лучше, уже созданный объект B) в качестве параметров конструктору 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. Если это проблема, я все же настоятельно рекомендую провести рефакторинг.

person ptomato    schedule 15.10.2011
comment
К сожалению, оба они совершенно не связаны, и это загрязнит объект A даже больше, чем просто использование свойств. - person user996839; 15.10.2011
comment
Звучит как главный кандидат на рефакторинг для меня. Тем не менее, я добавлю еще несколько предложений, о которых я подумал... - person ptomato; 16.10.2011
comment
Передача не свойственных аргументов конструктору A, похоже, соответствует тому, что меня интересует. У вас есть какой-нибудь указатель/пример того, как это сделать? - person user996839; 16.10.2011
comment
Да, но для этого требуется отложить инициализацию B до тех пор, пока вы фактически не создадите объект A. Я добавлю несколько советов к моему ответу. - person ptomato; 17.10.2011
comment
Спасибо, я не совсем понял, что вы имели в виду раньше. В принципе, это то, что делает и Валя. Поскольку я не создаю виджет, ограничение использования функции _new не является проблемой. - person user996839; 17.10.2011

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

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

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

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

person Jens Mühlenhoff    schedule 21.09.2016