[[PageOutline]] = Reference counting with `GRefPtr` = In the GObject object model, instances are reference-counted. To ease handling those in !WebKitGTK+ code, the `GRefPtr` 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: * [source:trunk/Source/WTF/wtf/gobject/GRefPtr.h Source/WTF/wtf/gobject/GRefPtr.h] * [source:trunk/Source/WTF/wtf/gobject/GRefPtr.cpp Source/WTF/wtf/gobject/GRefPtr.cpp] == Usage == === Creation === Creating a `GRefPtr` initializes it to `nullptr`: {{{ #!cpp GRefPtr context; // Check always succeeds, nullptr is the default value. ASSERT(!context); }}} === Destruction === When a `GRefPtr` goes is destroyed, it decreases the reference count of the object it holds. === Adopting a reference === 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 (and very likely would cause a leak). 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: {{{ #!cpp // Incorrect: The created object has *two* references, even // when referenced only from the “context” variable. GRefPtr context = g_main_context_new(); }}} And this is correct: {{{ #! // Correct: The newly created object has only one reference GRefPtr 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: {{{ #!cpp void doWithData(GByteArray* data) { GRefPtr dataLocal1 = data; GRefPtr dataLocal2 = dataLocal1; } }}} === 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: {{{ #!cpp void show(GRefPtr& widget) { gtk_widget_show_all(widget.get()); } }}} == Floating references == Some types have a ''floating reference'' when created, for example `GtkWidget` and derived types and `GVariant`. Most of the time 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: {{{ #!cpp GRefPtr variant = adoptGRef(g_variant_new("s", "Incorrect usage")); }}} Correct usage: {{{ #!cpp GRefPtr variant = g_variant_new("s", "Floating reference is sank"); }}} == When to use == In the following cases it is recommended to use `GRefPtr`: * When holding references as attribute members of instances. Note that this also makes it easier to write accessor methods at the API level, as the refing/unrefing of objects is done automatically: {{{ #!cpp struct FooPrivate { GRefPtr someData; }; // Public API method void foo_set_data(Foo* foo, GVariant* data) { FooPrivate* priv = foo_get_private(foo); // Takes care of unrefing the previously held object // and also refing the passed object. priv->someData = data; } }}} * When using local references to objects which should be freed/unrefed when the local variable goes out of scope: {{{ #!cpp void doSomethingWithALocalReference() { GRefPtr temporaryData = g_variant_new("s", "SpamAndEggs"); // Use “temporaryData” as needed, it will be freed automatically // when the variable goes out of scope at the end of the function } }}} In the following cases it is ''not'' recommended to use `GRefPtr`: * When creating an initially unowned object —that is, it has a floating reference— which is going to be passed to another function/object that will consume the floating reference. For example: {{{ #!cpp GVariant* createData(int value) { // This function does not use the new value; the caller // is responsible of consuming the floating reference. return g_variant_new("(si)", "int", value); } void someOtherCode() { // Picks the GVariant created by the above function and // grabs the floating reference, to make sure intData is // freed when it goes out of scope. GRefPtr intData = createData(42); useIntData(intData); } }}}