# The GObject base class

The previous chapter discussed the details of GLib's Dynamic Type System. The GObject library also contains an implementation for a base fundamental type named GObject.

GObject is a fundamental classed instantiable type. It implements:

- Memory management with reference counting

- Construction/Destruction of instances

- Generic per-object properties with set/get function pairs

- Easy use of signals

All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer) inherit from GObject which is why it is important to understand the details of how it works.

## Object instantiation

The `g_object_new` family of functions can be used to instantiate any GType which inherits from the GObject base type. All these functions make sure the class and instance structures have been correctly initialized by GLib's type system and then invoke at one point or another the constructor class method which is used to:

- Allocate and clear memory through `g_type_create_instance`,

- Initialize the object's instance with the construction properties.

Although one can expect all class and instance members (except the fields pointing to the parents) to be set to zero, some consider it good practice to explicitly set them.

Once all construction operations have been completed and constructor properties set, the constructed class method is called.

Objects which inherit from GObject are allowed to override this constructed class method. The example below shows how ViewerFile overrides the parent's construction process:

    #define VIEWER_TYPE_FILE viewer_file_get_type ()
    G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)

    struct _ViewerFile
    {
      GObject parent_instance;

      /* instance members */
    };

    /* will create viewer_file_get_type and set viewer_file_parent_class */
    G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)

    static void
    viewer_file_constructed (GObject *obj)
    {
      /* update the object state depending on constructor properties */

      /* Always chain up to the parent constructed function to complete object
       * initialisation. */
      G_OBJECT_CLASS (viewer_file_parent_class)->constructed (obj);
    }

    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
      GObjectClass *object_class = G_OBJECT_CLASS (klass);

      object_class->constructed = viewer_file_constructed;
    }

    static void
    viewer_file_init (ViewerFile *self)
    {
      /* initialize the object */
    }

If the user instantiates an object ViewerFile with:

    ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);

If this is the first instantiation of such an object, the `viewer_file_class_init` function will be invoked after any `viewer_file_base_class_init` function. This will make sure the class structure of this new object is correctly initialized. Here, `viewer_file_class_init` is expected to override the object's class methods and setup the class' own methods. In the example above, the constructor method is the only overridden method: it is set to `viewer_file_constructor`.

Once `g_object_new` has obtained a reference to an initialized class structure, it invokes its constructor method to create an instance of the new object, if the constructor has been overridden in `viewer_file_class_init`. Overridden constructors must chain up to their parent’s constructor. In order to find the parent class and chain up to the parent class constructor, we can use the `viewer_file_parent_class` pointer that has been set up for us by the `G_DEFINE_TYPE` macro.

Finally, at one point or another, `g_object_constructor` is invoked by the last constructor in the chain. This function allocates the object's instance buffer through `g_type_create_instance` which means that the `instance_init` function is invoked at this point if one was registered. After `instance_init` returns, the object is fully initialized and should be ready to have its methods called by the user. When `g_type_create_instance` returns, `g_object_constructor` sets the construction properties (i.e. the properties which were given to `g_object_new`) and returns to the user's constructor.

The process described above might seem a bit complicated, but it can be summarized easily by the table below which lists the functions invoked by `g_object_new` and their order of invocation:

### `g_object_new`

Invocation time | Function invoked | Function's parameters | Remark
--- | --- | --- | ---
First call to `g_object_new` for target type | target type's `base_init` function | On the inheritance tree of classes from fundamental type to target type. `base_init` is invoked once for each class structure. | Never used in practice. Unlikely you will need it.
target type's `class_init` function | On target type's class structure | Here, you should make sure to initialize or override class methods (that is, assign to each class' method its function pointer) and create the signals and the properties associated to your object.
interface's `base_init` function | On interface's vtable |
interface's `interface_init` function | On interface's vtable |

Each call to `g_object_new` for target type

target type's class `constructor` method: `GObjectClass->constructor`

On object's instance

If you need to handle construct properties in a custom way, or implement a singleton class, override the constructor method and make sure to chain up to the object's parent class before doing your own initialization. In doubt, do not override the constructor method.

type's `instance_init` function

On the inheritance tree of classes from fundamental type to target type. the `instance_init` provided for each type is invoked once for each instance structure.

Provide an `instance_init` function to initialize your object before its construction properties are set. This is the preferred way to initialize a GObject instance. This function is equivalent to C++ constructors.

target type's class `constructed` method: `GObjectClass->constructed` | On object's instance | If you need to perform object initialization steps after all construct properties have been set. This is the final step in the object initialization process, and is only called if the `constructor` method returned a new object instance (rather than, for example, an existing singleton).

Readers should feel concerned about one little twist in the order in which functions are invoked: while, technically, the class' constructor method is called before the GType's `instance_init` function (since `g_type_create_instance` which calls `instance_init` is called by `g_object_constructor` which is the top-level class constructor method and to which users are expected to chain to), the user's code which runs in a user-provided constructor will always run after GType's `instance_init` function since the user-provided constructor must (you've been warned) chain up before doing anything useful.

## Object memory management

The memory-management API for GObjects is a bit complicated but the idea behind it is pretty simple: the goal is to provide a flexible model based on reference counting which can be integrated in applications which use or require different memory management models (such as garbage collection). The methods which are used to manipulate this reference count are described below.

### Reference count

The functions `g_object_ref`/`g_object_unref` respectively increase and decrease the reference count. These functions are thread-safe. `g_clear_object` is a convenience wrapper around `g_object_unref` which also clears the pointer passed to it.

The reference count is initialized to one by `g_object_new` which means that the caller is currently the sole owner of the newly-created reference. When the reference count reaches zero, that is, when `g_object_unref` is called by the last client holding a reference to the object, the dispose and the finalize class methods are invoked.

Finally, after finalize is invoked, `g_type_free_instance` is called to free the object instance. Depending on the memory allocation policy decided when the type was registered (through one of the `g_type_register_*` functions), the object's instance memory will be freed or returned to the object pool for this type. Once the object has been freed, if it was the last instance of the type, the type's class will be destroyed as described in and .

The table below summarizes the destruction process of a GObject:

#### `g_object_unref`

Invocation time | Function invoked | Function's parameters | Remark
--- | --- | --- | ---

Last call to `g_object_unref` for an instance of target type

target type's dispose class function

GObject instance

When dispose ends, the object should not hold any reference to any other member object. The object is also expected to be able to answer client method invocations (with possibly an error code but no memory violation) until finalize is executed. dispose can be executed more than once. dispose should chain up to its parent implementation just before returning to the caller.

target type's finalize class function | GObject instance | Finalize is expected to complete the destruction process initiated by dispose. It should complete the object's destruction. finalize will be executed only once. finalize should chain up to its parent implementation just before returning to the caller. The reason why the destruction process is split is two different phases is explained in .
Last call to `g_object_unref` for the last instance of target type | interface's `interface_finalize` function | On interface's vtable | Never used in practice. Unlikely you will need it.
interface's `base_finalize` function | On interface's vtable | Never used in practice. Unlikely you will need it.
target type's `class_finalize` function | On target type's class structure | Never used in practice. Unlikely you will need it.
type's `base_finalize` function | On the inheritance tree of classes from fundamental type to target type. `base_init` is invoked once for each class structure. | Never used in practice. Unlikely you will need it.

### Weak References

Weak references are used to monitor object finalization: `g_object_weak_ref` adds a monitoring callback which does not hold a reference to the object but which is invoked when the object runs its dispose method. As such, each weak ref can be invoked more than once upon object finalization (since dispose can run more than once during object finalization).

`g_object_weak_unref` can be used to remove a monitoring callback from the object.

Weak references are also used to implement `g_object_add_weak_pointer` and `g_object_remove_weak_pointer`. These functions add a weak reference to the object they are applied to which makes sure to nullify the pointer given by the user when object is finalized.

Similarly, GWeakRef can be used to implement weak references if thread safety is required.

### Reference counts and cycles

GObject's memory management model was designed to be easily integrated in existing code using garbage collection. This is why the destruction process is split in two phases: the first phase, executed in the dispose handler is supposed to release all references to other member objects. The second phase, executed by the finalize handler is supposed to complete the object's destruction process. Object methods should be able to run without program error in-between the two phases.

This two-step destruction process is very useful to break reference counting cycles. While the detection of the cycles is up to the external code, once the cycles have been detected, the external code can invoke `g_object_run_dispose` which will indeed break any existing cycles since it will run the dispose handler associated to the object and thus release all references to other objects.

This explains one of the rules about the dispose handler stated earlier: the dispose handler can be invoked multiple times. Let's say we have a reference count cycle: object A references B which itself references object A. Let's say we have detected the cycle and we want to destroy the two objects. One way to do this would be to invoke `g_object_run_dispose` on one of the objects.

If object A releases all its references to all objects, this means it releases its reference to object B. If object B was not owned by anyone else, this is its last reference count which means this last unref runs B's dispose handler which, in turn, releases B's reference on object A. If this is A's last reference count, this last unref runs A's dispose handler which is running for the second time before A's finalize handler is invoked !

The above example, which might seem a bit contrived, can really happen if GObjects are being handled by language bindings — hence the rules for object destruction should be closely followed.

## Object properties

One of GObject's nice features is its generic get/set mechanism for object properties. When an object is instantiated, the object's `class_init` handler should be used to register the object's properties with `g_object_class_install_properties`.

The best way to understand how object properties work is by looking at a real example of how it is used:

    /************************************************/
    /* Implementation                               */
    /************************************************/

    enum
    {
      PROP_FILENAME = 1,
      PROP_ZOOM_LEVEL,
      N_PROPERTIES
    };

    static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };

    static void
    viewer_file_set_property (GObject      *object,
                              guint         property_id,
                              const GValue *value,
                              GParamSpec   *pspec)
    {
      ViewerFile *self = VIEWER_FILE (object);

      switch (property_id)
        {
        case PROP_FILENAME:
          g_free (self->priv->filename);
          self->priv->filename = g_value_dup_string (value);
          g_print ("filename: %s\n", self->priv->filename);
          break;

        case PROP_ZOOM_LEVEL:
          self->priv->zoom_level = g_value_get_uint (value);
          g_print ("zoom level: &percnt;u\n", self->priv->zoom_level);
          break;

        default:
          /* We don't have any other property... */
          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
          break;
        }
    }

    static void
    viewer_file_get_property (GObject    *object,
                              guint       property_id,
                              GValue     *value,
                              GParamSpec *pspec)
    {
      ViewerFile *self = VIEWER_FILE (object);

      switch (property_id)
        {
        case PROP_FILENAME:
          g_value_set_string (value, self->priv->filename);
          break;

        case PROP_ZOOM_LEVEL:
          g_value_set_uint (value, self->priv->zoom_level);
          break;

        default:
          /* We don't have any other property... */
          G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
          break;
        }
    }

    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
      GObjectClass *object_class = G_OBJECT_CLASS (klass);

      object_class->set_property = viewer_file_set_property;
      object_class->get_property = viewer_file_get_property;

      obj_properties[PROP_FILENAME] =
        g_param_spec_string ("filename",
                             "Filename",
                             "Name of the file to load and display from.",
                             NULL  /* default value */,
                             G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));

      obj_properties[PROP_ZOOM_LEVEL] =
        g_param_spec_uint ("zoom-level",
                           "Zoom level",
                           "Zoom level to view the file at.",
                           0  /* minimum value */,
                           10 /* maximum value */,
                           2  /* default value */,
                           G_PARAM_READWRITE));

      g_object_class_install_properties (object_class,
                                         N_PROPERTIES,
                                         obj_properties);
    }

    /************************************************/
    /* Use                                          */
    /************************************************/

    ViewerFile *file;
    GValue val = G_VALUE_INIT;

    file = g_object_new (VIEWER_TYPE_FILE, NULL);

    g_value_init (&val, G_TYPE_UINT);
    g_value_set_char (&val, 11);

    g_object_set_property (G_OBJECT (file), "zoom-level", &val);

    g_value_unset (&val);

The client code above looks simple but a lot of things happen under the hood:

`g_object_set_property` first ensures a property with this name was registered in file's `class_init` handler. If so it walks the class hierarchy, from bottom-most most-derived type, to top-most fundamental type to find the class which registered that property. It then tries to convert the user-provided GValue into a GValue whose type is that of the associated property.

If the user provides a signed char GValue, as is shown here, and if the object's property was registered as an unsigned int, `g_value_transform` will try to transform the input signed char into an unsigned int. Of course, the success of the transformation depends on the availability of the required transform function. In practice, there will almost always be a transformation Its behaviour might not be what you expect but it is up to you to actually avoid relying on these transformations. which matches and conversion will be carried out if needed.

After transformation, the GValue is validated by `g_param_value_validate` which makes sure the user's data stored in the GValue matches the characteristics specified by the property's GParamSpec. Here, the GParamSpec we provided in `class_init` has a validation function which makes sure that the GValue contains a value which respects the minimum and maximum bounds of the GParamSpec. In the example above, the client's GValue does not respect these constraints (it is set to 11, while the maximum is 10). As such, the `g_object_set_property` function will return with an error.

If the user's GValue had been set to a valid value, `g_object_set_property` would have proceeded with calling the object's `set_property` class method. Here, since our implementation of ViewerFile did override this method, execution would jump to `viewer_file_set_property` after having retrieved from the GParamSpec the param_id It should be noted that the param_id used here need only to uniquely identify each GParamSpec within the ViewerFileClass such that the switch used in the set and get methods actually works. Of course, this locally-unique integer is purely an optimization: it would have been possible to use a set of if (strcmp (a, b) == 0) {} else if (strcmp (a, b) == 0) {} statements. which had been stored by `g_object_class_install_property`.

Once the property has been set by the object's `set_property` class method, execution returns to `g_object_set_property` which makes sure that the "notify" signal is emitted on the object's instance with the changed property as parameter unless notifications were frozen by `g_object_freeze_notify`.

`g_object_thaw_notify` can be used to re-enable notification of property modifications through the “notify” signal. It is important to remember that even if properties are changed while property change notification is frozen, the "notify" signal will be emitted once for each of these changed properties as soon as the property change notification is thawed: no property change is lost for the "notify" signal, although multiple notifications for a single property are compressed. Signals can only be delayed by the notification freezing mechanism.

It sounds like a tedious task to set up GValues every time when one wants to modify a property. In practice one will rarely do this. The functions `g_object_set_property` and `g_object_get_property` are meant to be used by language bindings. For application there is an easier way and that is described next.

### Accessing multiple properties at once

It is interesting to note that the `g_object_set` and `g_object_set_valist` (variadic version) functions can be used to set multiple properties at once. The client code shown above can then be re-written as:

    ViewerFile *file;
    file = /* */;
    g_object_set (G_OBJECT (file),
                  "zoom-level", 6,
                  "filename", "~/some-file.txt",
                  NULL);

This saves us from managing the GValues that we were needing to handle when using `g_object_set_property`. The code above will trigger one notify signal emission for each property modified.

Equivalent `_get` versions are also available: `g_object_get` and `g_object_get_valist` (variadic version) can be used to get numerous properties at once.

These high level functions have one drawback — they don't provide a return value. One should pay attention to the argument types and ranges when using them. A known source of errors is to pass a different type from what the property expects; for instance, passing an integer when the property expects a floating point value and thus shifting all subsequent parameters by some number of bytes. Also forgetting the terminating `NULL` will lead to undefined behaviour.

This explains how `g_object_new`, `g_object_newv` and `g_object_new_valist` work: they parse the user-provided variable number of parameters and invoke `g_object_set` on the parameters only after the object has been successfully constructed. The "notify" signal will be emitted for each property set.