Chaining up

Chaining up is often loosely defined by the following set of conditions:

There are many uses to this idiom:

I am personally not really convinced any of the last two uses are really a good idea but since this programming idiom is often used, this section attemps to explain how to implement it.

To explicitely chain up to the implementation of the virtual method in the parent class, you first need a handle to the original parent class structure. This pointer can then be used to access the original class function pointer and invoke it directly. [12]

The function g_type_class_peek_parent is used to access the original parent class structure. Its input is a pointer to the class of the derived object and it returns a pointer to the original parent class structure. The code below shows how you could use it:

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 */
}

A lot of people who use this idiom in GTK+ store the parent class structure pointer in a global static variable to avoid the costly call to g_type_class_peek_parent for each function call. Typically, the class_init callback initializes the global static variable. gtk/gtkhscale.c does this.



[12] The original adjective used in this sentence is not innocuous. To fully understand its meaning, you need to recall how class structures are initialized: for each object type, the class structure associated to this object is created by first copying the class structure of its parent type (a simple memcpy) and then by invoking the class_init callback on the resulting class structure. Since the class_init callback is responsible for overwriting the class structure with the user re-implementations of the class methods, we cannot merely use the modified copy of the parent class structure stored in our derived instance. We want to get a copy of the class structure of an instance of the parent class.