GTK + стиль Typecast для аргументов функции - PullRequest
4 голосов
/ 04 октября 2010

В вызовах GTK + аргументы должны (но не обязательно) приводиться от GtkWidget к наиболее определенному классу, необходимому функции перед передачей аргумента. Например, иногда я вижу

some_call(GTK_WINDOW(window));

а в другое время вижу

some_call((GtkWindow *) window);

Какая разница?

Ответы [ 3 ]

7 голосов
/ 04 октября 2010

GTK_WINDOW - это макрос, который выполняет приведение.

Как видно здесь

#define GTK_WINDOW(obj)  (GTK_CHECK_CAST ((obj), GTK_TYPE_WINDOW, GtkWindow))

Снова

#define GTK_CHECK_CAST G_TYPE_CHECK_INSTANCE_CAST

и

#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type))

, что ...

#define _G_TYPE_CIC(ip,gt,ct)    \
    ((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt))

Код для g_type_check_instance_cast банкаможно найти здесь

GTypeInstance*
g_type_check_instance_cast (GTypeInstance *type_instance,
                            GType          iface_type)
{
  if (type_instance)
    {
      if (type_instance->g_class)
        {
          TypeNode *node, *iface;
          gboolean is_instantiatable, check;

          node = lookup_type_node_I (type_instance->g_class->g_type);
          is_instantiatable = node && node->is_instantiatable;
          iface = lookup_type_node_I (iface_type);
          check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
          if (check)
            return type_instance;

          if (is_instantiatable)
            g_warning ("invalid cast from `%s' to `%s'",
                       type_descriptive_name_I (type_instance->g_class->g_type),
                       type_descriptive_name_I (iface_type));
          else
            g_warning ("invalid uninstantiatable type `%s' in cast to `%s'",
                       type_descriptive_name_I (type_instance->g_class->g_type),
                       type_descriptive_name_I (iface_type));
        }
      else
        g_warning ("invalid unclassed pointer in cast to `%s'",
                   type_descriptive_name_I (iface_type));
    }

  return type_instance;
}
2 голосов
/ 04 октября 2010

Первый - это макрос, который может как проверить, возможно ли приведение, так и выполнить приведение.Это GTKs версия / попытка безопасного типа.Вы должны использовать это.

0 голосов
/ 04 октября 2010

GTK_WINDOW () - это просто макрос, который будет выглядеть примерно так:

#define GTK_WINDOW(a) ((GtkWindow*)a)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...