Version 2 (modified by 11 years ago) ( diff ) | ,
---|
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");