|
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](home.png)
|
|
Packit |
ae235b |
![Up](up.png)
|
|
Packit |
ae235b |
![Prev](left.png)
|
|
Packit |
ae235b |
![Next](right.png)
|
|
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 |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
A_CLASS (b_parent_class)->method_to_call (obj, some_param);
|
|
Packit |
ae235b |
|
|
Packit |
ae235b |
|
|
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>
|