c++-gtk-utils
Public Member Functions | List of all members
Cgu::GobjHandle< T > Class Template Reference

This is a handle for managing the reference count of GObjects. More...

#include <c++-gtk-utils/gobj_handle.h>

Public Member Functions

 GobjHandle (T *ptr=0) noexcept
 
void reset (T *ptr=0)
 
 GobjHandle (const GobjHandle &gobj) noexcept
 
 GobjHandle (GobjHandle &&gobj) noexcept
 
GobjHandleoperator= (const GobjHandle &gobj)
 
GobjHandleoperator= (GobjHandle &&gobj)
 
T * get () const noexcept
 
T & operator* () const noexcept
 
T * operator-> () const noexcept
 
 operator T* () const noexcept
 
 ~GobjHandle ()
 

Detailed Description

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.

Typical usage might be, for example, as follows:

using namespace Cgu;
GobjHandle<GtkListStore> store(gtk_list_store_new(1, G_TYPE_STRING));
[ ... fill the list store ... ]
GobjHandle<GtkWidget> view(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store.get()));
// 'view' will take sole ownership of the list store when 'store' goes out of scope, or
// 'store' could be kept alive so that the list store will survive removal from the view
[ ... set up an interface including a GtkVBox 'vbox' which will hold the tree view ... ]
gtk_container_add(GTK_CONTAINER(vbox), view);
// 'vbox' will take sole ownership of the tree view when 'view' goes out of scope, or
// 'view' could be kept alive so that the tree view will survive removal from the vbox

Constructor & Destructor Documentation

◆ GobjHandle() [1/3]

template<class T >
Cgu::GobjHandle< T >::GobjHandle ( T *  ptr = 0)
inlineexplicitnoexcept

The constructor does not throw. g_object_ref_sink() is called if the managed object has a floating reference.

Parameters
ptrThe object which the GobjHandle is to manage (if any).
Note
The object passed should not normally be already owned by a GTK container or managed by any other GobjHandle object. If it is, g_object_ref() must be called explicitly by the user code.

◆ GobjHandle() [2/3]

template<class T >
Cgu::GobjHandle< T >::GobjHandle ( const GobjHandle< T > &  gobj)
inlinenoexcept

The copy constructor does not throw. It increments the reference count of the managed object.

Parameters
gobjThe handle to be copied.

◆ GobjHandle() [3/3]

template<class T >
Cgu::GobjHandle< T >::GobjHandle ( GobjHandle< T > &&  gobj)
inlinenoexcept

The move constructor does not throw. It has move semantics.

Parameters
gobjThe handle to be moved.

◆ ~GobjHandle()

template<class T >
Cgu::GobjHandle< T >::~GobjHandle ( )
inline

The destructor does not throw. It decrements the reference count of the managed object (if any), so destroying it if the reference count thereby becomes 0.

Member Function Documentation

◆ get()

template<class T >
T* Cgu::GobjHandle< T >::get ( ) const
inlinenoexcept

This method does not throw.

Returns
A pointer to the handled GObject (or NULL if none is handled).

◆ operator T*()

template<class T >
Cgu::GobjHandle< T >::operator T* ( ) const
inlinenoexcept

This method does not throw.

Returns
A pointer to the handled GObject (or NULL if none is handled).

◆ operator*()

template<class T >
T& Cgu::GobjHandle< T >::operator* ( ) const
inlinenoexcept

This method does not throw.

Returns
A reference to the handled GObject.

◆ operator->()

template<class T >
T* Cgu::GobjHandle< T >::operator-> ( ) const
inlinenoexcept

This method does not throw.

Returns
A pointer to the handled GObject (or NULL if none is handled).

◆ operator=() [1/2]

template<class T >
GobjHandle& Cgu::GobjHandle< T >::operator= ( const GobjHandle< T > &  gobj)
inline

This method decrements the reference count of the former managed object (if any), so destroying it if the reference count thereby becomes 0, and increments the reference count of the new managed object. This method does not throw (unless this method destroys a sub-classed GObject which has a member object whose destructor throws).

Parameters
gobjThe assignor.
Returns
The GobjHandle object after assignment.

◆ operator=() [2/2]

template<class T >
GobjHandle& Cgu::GobjHandle< T >::operator= ( GobjHandle< T > &&  gobj)
inline

This method decrements the reference count of the former managed object (if any), so destroying it if the reference count thereby becomes 0, and has move semantics with respect to the new managed object. This method does not throw (unless this method destroys a sub-classed GObject which has a member object whose destructor throws).

Parameters
gobjThe handle to be moved.
Returns
The GobjHandle object after the move operation.

◆ reset()

template<class T >
void Cgu::GobjHandle< T >::reset ( T *  ptr = 0)
inline

Causes the handle to cease to manage its managed object (if any) and decrements its reference count, so destroying it if the reference count thereby becomes 0. If the argument passed is not NULL, the handle will manage the new object passed and g_object_ref_sink() is called if the new object has a floating reference. This method does not throw (unless this method destroys a sub-classed GObject which has a member object whose destructor throws).

Parameters
ptrNULL (the default), or a new object to manage.
Note
The new object passed should not normally be already owned by a GTK container or managed by any other GobjHandle object. If it is, g_object_ref() must be called explicitly by the user code.

The documentation for this class was generated from the following file:
Cgu
Definition: application.h:44
Cgu::GobjHandle
This is a handle for managing the reference count of GObjects.
Definition: gobj_handle.h:148