Here’s some trivial note on using GObject library.
1. Private members
Recall our definition of Base type:
NOTE: PLEASE READ ALL COMMENT CAREFULLY.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
/* Base object struct */
typedefstruct_Base{
GTypeInstance parent;
/* instance variable, should be hidden */
gint base_instance_i;
}Base;
/* Base class struct */
typedefstruct_BaseClass{
GTypeClass parent;
/* instance method, used as a virtual method */
void(*base_instance_dump)(struct_Base*instance);
}BaseClass;
It expose the visibility of base_instance_i field. We should keep encapsulation in OOP. GObject library has support for this. We can define the class as:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* private data of Base object */
typedefstruct_FakeBasePrivate FakeBasePrivate;
/* Base object struct */
typedefstruct_FakeBase{
/* GObject as the first field */
GObject parent;
/* private data */
FakeBasePrivate*priv;
}FakeBase;
/* Base class struct */
typedefstruct_FakeBaseClass{
/*
* The type GObject is supposed to be the base class of other user-defined classes.
* - Reference count support.
* - Support adding properties to GObject subclasses.
* - Support signals for asynchronized event handling like "event" in C#.
*/
/* GObjectClass as the first field */
GObjectClass parent;
/*
* Since glib 2.24, there're new functions to keep privacy:
* - g_type_add_class_private()
* - g_type_class_get_private()
*/
/* private static field */
gint version;
/* private dynamic field */
gchar*author;
/* instance method, used as a virtual method */
void(*virtual_dump)(struct_FakeBase*instance);
}FakeBaseClass;
We declare a new FakeBasePrivate struct to contain all private field used in FakeBase type. And the private struct is defined in *.c file, so its internal representation remains invisible. Then in *.c file, we got:
The private member is malloc in class_init() callback, and is ready to use after invoking instance_init(). When we will use property mechanism to get/set these private field later.