wiki:GRefPtr

Version 1 (modified by Adrian Perez de Castro, 10 years ago) (diff)

Initial version

Reference counting with GRefPtr<T>

In the GLib/GObject/GTK+ object model, instances are reference-counted. To ease handling those in !WebKitGTK+ code, the GRefPtr<T> template is provided. It keeps a pointer to a reference-counted and takes care of properly increasing and decreasing the reference counts for object being held. Helper functions are provided as well (e.g. adoptGRef()).

Sources:

Usage

Creation

Creating a GRefPtr<T> initializes it to nullptr:

GRefPtr<GtkWidget> widget;
// Check always succeeds, nullptr is the default value.
ASSERT(!widget);

It is also possible to pass an initial value to the constructor — it can be both a raw pointer or a GRefPtr of the same type:

void doWithWidget(GtkWidget* widget) {
    GRefPtr<GtkWidget> widgetLocal1(widget); // Increases the reference counter of “widget”
    GRefPtr<GtkWidget> widgetLocal2(widgetLocal1); // ...and again.
}

When a GRefPtr<T> goes is destroyed, it decreases the reference count of the object it holds.

Adopting a pointer

Sometimes it is desirable to store a pointer in a GRefPtr without increasing the reference counter. The main use case is assigning a newly created instance to a GRefPtr: the newly created instance already has a reference count of one and assigning it to a GRefPtr would increase the reference count to two, which would be incorrect. To avoid this, the adoptGRef() helper function is provided. This function creates a GRefPtr without increasing the reference counter of the object it holds. This is incorrect:

// Incorrect: The created object has *two* references, even
// when referenced only from the “context” variable.
GRefPtr<GMainContext> context = g_main_context_new();

And this is correct:

#!
// Correct: The newly created object has only one reference
GRefPtr<GMainContext> context = adoptGRef(g_main_context_new());

Assignment

Assigning to a GRefPtr increases the reference count for the pointer being assigned. Both raw pointers and other GRefPtr instances can be assigned:

void doWithWidget(GtkWidget* widget) {
    GRefPtr<GtkWidget> widgetLocal1 = widget;
    GRefPtr<GtkWidget> widgetLocal2 = widgetLocal1;
}

Raw pointer

To obtain the raw pointer use the get() method. This is typically used when calling functions from support libraries used by the port (GLib, GTK+, etc). For example:

void show(GRefPtr<GtkWidget>& widget) {
    gtk_widget_show_all(widget.get());
}

Floating references

Instances of most types have a floating reference when created. Most GObject-derived types, but also some other types have floating references (GVariant is one of those). It is incorrect to use adoptGRef() on newly created instances of types which use floating references: the floating reference has to be converted on a full reference. Assigning to a GRefPtr will convert the floating reference to a full reference.

Incorrect usage:

GRefPtr<GVariant> variant = adoptGRef(g_variant_new("s", "Incorrect usage"));

Correct usage:

GRefPtr<GVariant> variant = g_variant_new("s", "Floating reference is sank");