The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

Как определять и реализовывать Интерфейсы?

Как определять Интерфейсы?
Как определить реализацию Интерфейса?
Предпосылки определения Интерфейса
Свойства Интерфейса

Как определять Интерфейсы?

Большая часть определения интерфейса уже показана “Non-instantiable classed types: Interfaces.” но я чувствую что нужно показать как конкретно создаётся интерфейс. Исходные коды примеров связанных с этим разделом можно найти в исходном пакете документации, в файле sample/interface/maman-ibaz.{h|c}.

Как и раньше, сначала получаем правильный заголовок:

#ifndef MAMAN_IBAZ_H
#define MAMAN_IBAZ_H

#include <glib-object.h>

#define MAMAN_TYPE_IBAZ                (maman_ibaz_get_type ())
#define MAMAN_IBAZ(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_IBAZ, MamanIbaz))
#define MAMAN_IS_IBAZ(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_IBAZ))
#define MAMAN_IBAZ_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MAMAN_TYPE_IBAZ, MamanIbazInterface))


typedef struct _MamanIbaz MamanIbaz; /* макет объекта */
typedef struct _MamanIbazInterface MamanIbazInterface;

struct _MamanIbazInterface {
  GTypeInterface parent;

  void (*do_action) (MamanIbaz *self);
};

GType maman_ibaz_get_type (void);

void maman_ibaz_do_action (MamanIbaz *self);

#endif /*MAMAN_IBAZ_H*/

Этот код похож на обычную GType которая наследует GObject за исключением некоторых деталей:

  • _GET_CLASS макрос называется _GET_INTERFACE и реализуется не с помощью G_TYPE_INSTANCE_GET_CLASS, а с помощью G_TYPE_INSTANCE_GET_INTERFACE.

  • Тип экземпляра MamanIbaz определён не полностью: он используется просто как абстрактный тип который представляет экземпляр любого объекта реализующего интерфейс.

Реализация самого типа MamanIbaz тривиальна:

  • maman_ibaz_get_type регистрирует тип в системе типов.

  • maman_ibaz_base_init как ожидается регистрирует интерфейсные сигналы если они есть (позже мы рассмотрим как их использовать). Убедитесь что используете статичную локальную логическую переменную чтобы не выполнять код инициализации дважды (как описано в “Interface Initialization”, base_init выполняется один раз для каждой реализованной инстанциации интерфейса)

  • maman_ibaz_do_action разыменовывает структуру класса для доступа к связанным с ней функциям класса и их вызова.

static void
maman_ibaz_base_init (gpointer g_class)
{
  static gboolean initialized = FALSE;

  if (!initialized) {
    /* здесь создаём сигналы интерфейса. */
    initialized = TRUE;
  }
}

GType
maman_ibaz_get_type (void)
{
  static GType type = 0;
  if (type == 0) {
    static const GTypeInfo info = {
      sizeof (MamanIbazInterface),
      maman_ibaz_base_init,   /* base_init */
      NULL,   /* base_finalize */
      NULL,   /* class_init */
      NULL,   /* class_finalize */
      NULL,   /* class_data */
      0,
      0,      /* n_preallocs */
      NULL    /* instance_init */
    };
    type = g_type_register_static (G_TYPE_INTERFACE, "MamanIbaz", &info, 0);
  }
  return type;
}

void maman_ibaz_do_action (MamanIbaz *self)
{
  MAMAN_IBAZ_GET_INTERFACE (self)->do_action (self);
}




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру