Blame docs/reference/gobject/html/howto-gobject-chainup.html

Packit ae235b
Packit ae235b
<html>
Packit ae235b
<head>
Packit ae235b
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Packit ae235b
<title>Chaining up: GObject Reference Manual</title>
Packit ae235b
<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
Packit ae235b
<link rel="home" href="index.html" title="GObject Reference Manual">
Packit ae235b
<link rel="up" href="howto-gobject.html" title="How to define and implement a new GObject">
Packit ae235b
<link rel="prev" href="howto-gobject-methods.html" title="Object methods">
Packit ae235b
<link rel="next" href="howto-interface.html" title="How to define and implement interfaces">
Packit ae235b
<meta name="generator" content="GTK-Doc V1.27 (XML mode)">
Packit ae235b
<link rel="stylesheet" href="style.css" type="text/css">
Packit ae235b
</head>
Packit ae235b
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
Packit ae235b
Packit ae235b
Packit ae235b
Home
Packit ae235b
Up
Packit ae235b
Prev
Packit ae235b
Next
Packit ae235b
Packit ae235b
Packit ae235b

Packit ae235b
Chaining up
Packit ae235b

Chaining up is often loosely defined by the following set of

Packit ae235b
    conditions:
Packit ae235b
      

Packit ae235b
    Packit ae235b
  • Parent class A defines a public virtual method named foo and

  • Packit ae235b
            provides a default implementation.

    Packit ae235b
  • Child class B re-implements method foo.

  • Packit ae235b
  • B’s implementation of foo calls (‘chains up to’) its parent class A’s implementation of foo.

  • Packit ae235b
    Packit ae235b

    Packit ae235b
          There are various uses of this idiom:
    Packit ae235b
          

    Packit ae235b
      Packit ae235b
    • You need to extend the behaviour of a class without modifying its code. You create

    • Packit ae235b
                a subclass to inherit its implementation, re-implement a public virtual method to modify the behaviour
      Packit ae235b
                and chain up to ensure that the previous behaviour is not really modified, just extended.
      Packit ae235b
                

      Packit ae235b
    • You need to implement the

    • Packit ae235b
                Chain
      Packit ae235b
                Of Responsibility pattern: each object of the inheritance
      Packit ae235b
                tree chains up to its parent (typically, at the beginning or the end of the method) to ensure that
      Packit ae235b
                each handler is run in turn.

      Packit ae235b
      Packit ae235b

      Packit ae235b
          

      Packit ae235b

      Packit ae235b
            To explicitly chain up to the implementation of the virtual method in the parent class, 
      Packit ae235b
            you first need a handle to the original parent class structure. This pointer can then be used to 
      Packit ae235b
            access the original virtual function pointer and invoke it directly.
      Packit ae235b
            <sup class="footnote">[7]</sup>
      Packit ae235b
          

      Packit ae235b

      Packit ae235b
            Use the parent_class pointer created and initialized
      Packit ae235b
            by the
      Packit ae235b
            G_DEFINE_TYPE
      Packit ae235b
            family of macros, for instance:
      Packit ae235b

      Packit ae235b
      Packit ae235b
        
      Packit ae235b
          
      Packit ae235b
            
      Packit ae235b
              
      1
      Packit ae235b
      2
      Packit ae235b
      3
      Packit ae235b
      4
      Packit ae235b
      5
      Packit ae235b
      6
      Packit ae235b
      7
      Packit ae235b
      8
      Packit ae235b
      9
      Packit ae235b
      10
      Packit ae235b
      11
      Packit ae235b
      12
      Packit ae235b
      13
      Packit ae235b
      14
      Packit ae235b
              
      static void
      Packit ae235b
      b_method_to_call (B *obj, gint some_param)
      Packit ae235b
      {
      Packit ae235b
        /* do stuff before chain up */
      Packit ae235b
      Packit ae235b
        /* call the method_to_call() virtual function on the
      Packit ae235b
         * parent of BClass, AClass.
      Packit ae235b
         *
      Packit ae235b
         * remember the explicit cast to AClass*
      Packit ae235b
         */
      Packit ae235b
        A_CLASS (b_parent_class)->method_to_call (obj, some_param);
      Packit ae235b
      Packit ae235b
        /* do stuff after chain up */
      Packit ae235b
      }
      Packit ae235b
            
      Packit ae235b
          
      Packit ae235b
        
      Packit ae235b
      Packit ae235b
      Packit ae235b

      Packit ae235b
        

      Packit ae235b
      Packit ae235b


      Packit ae235b
      Packit ae235b
                The original adjective used in this sentence is not innocuous. To fully 
      Packit ae235b
                understand its meaning, recall how class structures are initialized: for each object type,
      Packit ae235b
                the class structure associated with this object is created by first copying the class structure of its
      Packit ae235b
                parent type (a simple memcpy) and then by invoking the class_init callback on
      Packit ae235b
                the resulting class structure. Since the class_init callback is responsible for overwriting the class structure
      Packit ae235b
                with the user re-implementations of the class methods, the modified copy of the parent class
      Packit ae235b
                structure stored in the derived instance cannot be used. A copy of the class structure of an instance of the parent
      Packit ae235b
                class is needed.
      Packit ae235b
              

      Packit ae235b
      Packit ae235b
      Packit ae235b
      Packit ae235b

      Generated by GTK-Doc V1.27
      Packit ae235b
      </body>
      Packit ae235b
      </html>