The OpenNET Project / Index page

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

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

Формирование цепочки

Формирование цепочки часто неточно определяется следующим набором условий:

Эту идиому можно использовать по разному:

Я лично не уверен что два последних способа использования являются хорошей идеей, н так как эта идиома программирования часто используется, этот раздел попытается объяснить как это реализуется.

Для явного формирования цепочки в реализации виртуального метода в родительском классе, вам сначала нужно обработать оригинальную структуру родительского класса. Этот указатель можно зтем использовать для доступа к оригинальному указателю функции класса и вызывать её непосредственно. [13]

Функция g_type_class_peek_parent используется для доступа к оригинальной родительской классовой структуре. Её ввод - это указатель на класс производного объекта и она возвращает указатель на оригинальную родительскую структуру класса. Код ниже показывает как вы должны её использовать:

static void
b_method_to_call (B *obj, int a)
{
  BClass *klass;
  AClass *parent_class;
  klass = B_GET_CLASS (obj);
  parent_class = g_type_class_peek_parent (klass);

  /* do stuff before chain up */
  parent_class->method_to_call (obj, a);
  /* do stuff after chain up */
}

Многие люди использующие эту идиому в GTK+ хранят указатель на родительскую классовую структуру в глобальной статической переменной, чтобы избегать расточительных вызовов g_type_class_peek_parent для каждого вызова функции. Обычно, class_init callback-функция инициализирует глобальную статичную переменную. Это делает gtk/gtkhscale.c.



[13] Оригинальное прилагательное используемое в этом предложении весьма вредное. Для полного понимания что это значит, вы должны повторить как сструктуры класса инициализируются: для каждого объектного типа, классовая структура привязанная к объекту создаётся с помощью начального копирования классовой сструктуры родительского типа (просто memcpy) а зтем вызывается class_init callback-функция в результирующей структуре. Так как class_init callback-функция отвечает за перезапись классовой сструктуры с пользовательской перереализацией методов класса, мы не можем просто использовать изменённую копию родительской сструктуры класса сохранённую в нашем производном экземпляре. Мы хотим получить копию классовой сструктуры экземпляра родительского класса.




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

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