Разобраться в объектах gtk и их иерархии
На протяжении полугода изучал Си и теперь приступил к изучению GTK. У меня возникли вопросы, на которые я пока что не смог найти ответа.
Правильно ли я понимаю, что объекты в gtk (например GtkWidget) являются по факту обычной структурой?
Как понять "иерархия объектов"? Например GtkWidget > GtkContainer > GtkBin > GtkWindow. Значит ли это, что GTKWindow включает в себя все элементы структуры GtkBin и имеет еще свои уникальные? То есть это выглядит примерно так:
struct GtkWindow {
уникальные для GtkWindow элементы структуры;
struct GtkBin _GtkBin
};
A GtkBin в свою очередь так:
struct GtkBin {
уникальные для GtkBin элементы структуры;
struct GtkContainer _GtkContainer
};
И так далее или как это реализовано?
Почему при создании нового окна с помощью gtk_window_new возвращается указатель на виджет, а не на окно? Ведь в gtk есть специальный объект для этого.
Что происходит при преобразовании в другой тип с помощью макросов например так: GTK_WINDOW(mainwin). Создается новая срктура, в которую добавляются новые элементы, если mainwin это GtkWidget?
Ответы (1 шт):
да, это структуры Простые обычные структуры. Просто оформлены по определенным правилам.
Не нужно гадать, можно посмотреть в исходники.
struct _GtkWindow { GtkBin bin; GtkWindowPrivate *priv; };только "базовая структура" указывается самой первой, что бы легко подсовывать "структуру наследника" там, где можно написать "родительскую структуру" (я специально в кавычки взял).
Честно не знаю, но думаю, что это такое соглашение. Хотя мне кажется, так легче было сделать многие функции - они получают указатель на "базовую структуру" и типы сходятся. А кому нужно - вверх подымет.
Обычный каст. Правда там ещё может быть и дополнительная проверка, что объект валидный. Опять же, можно посмотреть в сорцы
#define GTK_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WINDOW, GtkWindow)) #define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type)) /* --- implementation bits --- */ #ifndef G_DISABLE_CAST_CHECKS # define _G_TYPE_CIC(ip, gt, ct) \ ((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt)) # define _G_TYPE_CCC(cp, gt, ct) \ ((ct*) g_type_check_class_cast ((GTypeClass*) cp, gt)) #else /* G_DISABLE_CAST_CHECKS */ # define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip) # define _G_TYPE_CCC(cp, gt, ct) ((ct*) cp) #endif /* G_DISABLE_CAST_CHECKS */