template<class T>
class Cgu::GobjHandle< T >
This is a handle for managing the reference count of GObjects.
- See also
- MainWidgetBase GobjWeakHandle
This is a class which manages the reference count of GObjects. It does not maintain its own reference count, but interfaces with that kept by the glib object system.
GobjHandles are most useful to manage GObjects which are not also GtkWidgets or GInitiallyUnowned objects - GtkWidgets and GInitiallyUnowned objects have initial floating references which will result in them being automatically managed by the container in which they are held. Nonetheless, GobjHandles can be used to hold GtkWidgets and GInitiallyUnowned objects, as the constructor of a GobjHandle which takes a pointer will automatically take ownership of a newly created GtkWidget or GInitiallyUnowned object, by calling g_object_ref_sink(). Plain GObjects do not need to be sunk to be owned by the GobjHandle.
Note that g_object_ref_sink() is not called by the constructor taking a pointer if the floating reference has already been sunk, so if that constructor is passed an object already owned by a GTK+ container it will be necessary to call g_object_ref() on it explicitly. This behaviour will ensure that the handle behaves the same whether it is holding a plain GObject, or it is holding a GInitiallyUnowned/GtkWidget object. Generally however, where an object is already owned by a container, the object should be passed by another handle - ie by the copy constructor (or by the assignment operator), as those always increment the reference count automatically.
In other words, invoke the constructor taking a pointer only with a newly created object (whether a GObject, GInitiallyUnowned or GtkWidget object), and everything else will take care of itself. In this respect, GobjHandles work the same way as conventional shared pointer implementations managing objects allocated on free store. The same applies to the reset() method. (Care is required however if initializing a Cgu::GobjHandle with a widget or GObject object obtained from GtkBuilder, since these are not "newly created" in this sense. It is necessary to call g_object_ref() by hand in that case, since GtkBuilder does not by itself pass ownership of any objects it creates.)
Because any GTK+ containers themselves increment the reference count of a GObject or GtkWidget where they need to take ownership, an already-managed object held by a GobjHandle can safely be passed by pointer to a GTK+ container, and that is one of the intended usages. For that purpose, although the class has operator*() and operator->() dereferencing operators, and so has normal smart pointer functionality, as it is intended for use with the normal C GObject/pango/GTK+ interfaces, ordinary use would involve passing the handle to a function taking a pointer by means of the operatorT*() type conversion operator (which returns the underlying pointer), or by explicitly calling the get() method to obtain the underlying pointer.
The principal intended usage of GobjHandle is to automatically handle GObject reference counts and therefore to make GObjects exception-safe, but they also permit GObjects/GtkWidgets to be kept in standard C++ containers.
As of glib-2.8, g_object_ref() and g_object_unref() are thread safe, so with glib-2.8 or greater there can be different GobjHandle instances in different threads referencing the same GObject object. Of course, if that is done, this does not affect the need (or otherwise) in the particular use in question to lock anything other than the reference count - say when accessing the referenced object itself in different threads.
From version 1.2.12, the library provides ==, != and < comparison operators for GobjHandles, but only if the library is compiled with the --with-smart-ptr-comp option, or if the user code defines the symbol CGU_USE_SMART_PTR_COMPARISON before gobj_handle.h is first parsed. This is because, if user code has provided such operators for these smart pointers itself, a duplicated function definition would arise.
Typical usage might be, for example, as follows:
[ ... fill the list store ... ]
[ ... set up an interface including a GtkVBox 'vbox' which will hold the tree view ... ]
gtk_container_add(GTK_CONTAINER(vbox), view);