| 1 | = Reference counting with `GRefPtr<T>` = |
| 2 | |
| 3 | 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()`). |
| 4 | |
| 5 | Sources: |
| 6 | |
| 7 | * [source:trunk/Source/WTF/wtf/gobject/GRefPtr.h Source/WTF/wtf/gobject/GRefPtr.h] |
| 8 | * [source:trunk/Source/WTF/wtf/gobject/GRefPtr.cpp Source/WTF/wtf/gobject/GRefPtr.h] |
| 9 | |
| 10 | |
| 11 | == Usage == |
| 12 | |
| 13 | === Creation === |
| 14 | |
| 15 | Creating a `GRefPtr<T>` initializes it to `nullptr`: |
| 16 | {{{ |
| 17 | #!cpp |
| 18 | GRefPtr<GtkWidget> widget; |
| 19 | // Check always succeeds, nullptr is the default value. |
| 20 | ASSERT(!widget); |
| 21 | }}} |
| 22 | |
| 23 | 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: |
| 24 | {{{ |
| 25 | #!cpp |
| 26 | void doWithWidget(GtkWidget* widget) { |
| 27 | GRefPtr<GtkWidget> widgetLocal1(widget); // Increases the reference counter of “widget” |
| 28 | GRefPtr<GtkWidget> widgetLocal2(widgetLocal1); // ...and again. |
| 29 | } |
| 30 | }}} |
| 31 | |
| 32 | When a `GRefPtr<T>` goes is destroyed, it decreases the reference count of the object it holds. |
| 33 | |
| 34 | === Adopting a pointer === |
| 35 | |
| 36 | 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: |
| 37 | {{{ |
| 38 | #!cpp |
| 39 | // Incorrect: The created object has *two* references, even |
| 40 | // when referenced only from the “context” variable. |
| 41 | GRefPtr<GMainContext> context = g_main_context_new(); |
| 42 | }}} |
| 43 | |
| 44 | And this is correct: |
| 45 | {{{ |
| 46 | #! |
| 47 | // Correct: The newly created object has only one reference |
| 48 | GRefPtr<GMainContext> context = adoptGRef(g_main_context_new()); |
| 49 | }}} |
| 50 | |
| 51 | === Assignment === |
| 52 | |
| 53 | Assigning to a `GRefPtr` increases the reference count for the pointer being assigned. Both raw pointers and other `GRefPtr` instances can be assigned: |
| 54 | {{{ |
| 55 | #!cpp |
| 56 | void doWithWidget(GtkWidget* widget) { |
| 57 | GRefPtr<GtkWidget> widgetLocal1 = widget; |
| 58 | GRefPtr<GtkWidget> widgetLocal2 = widgetLocal1; |
| 59 | } |
| 60 | }}} |
| 61 | |
| 62 | |
| 63 | === Raw pointer === |
| 64 | |
| 65 | 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: |
| 66 | {{{ |
| 67 | #!cpp |
| 68 | void show(GRefPtr<GtkWidget>& widget) { |
| 69 | gtk_widget_show_all(widget.get()); |
| 70 | } |
| 71 | }}} |
| 72 | |
| 73 | |
| 74 | == Floating references == |
| 75 | |
| 76 | 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. |
| 77 | |
| 78 | Incorrect usage: |
| 79 | {{{ |
| 80 | #!cpp |
| 81 | GRefPtr<GVariant> variant = adoptGRef(g_variant_new("s", "Incorrect usage")); |
| 82 | }}} |
| 83 | |
| 84 | Correct usage: |
| 85 | {{{ |
| 86 | #!cpp |
| 87 | GRefPtr<GVariant> variant = g_variant_new("s", "Floating reference is sank"); |
| 88 | }}} |