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)
 
void reset (T *ptr=0)
 
 GobjHandle (const GobjHandle &gobj)
 
GobjHandleoperator= (const GobjHandle &gobj)
 
T * get () const
 
T & operator* () const
 
T * operator-> () const
 
 operator T * () const
 
 ~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.

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:

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

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

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.
template<class T>
Cgu::GobjHandle< T >::GobjHandle ( const GobjHandle< T > &  gobj)
inline

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

Parameters
gobjThe handle to be copied.
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

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

This method does not throw.

Returns
A pointer to the handled GObject (or NULL if none is handled).
template<class T>
Cgu::GobjHandle< T >::operator T * ( ) const
inline

This method does not throw.

Returns
A pointer to the handled GObject (or NULL if none is handled).
template<class T>
T& Cgu::GobjHandle< T >::operator* ( ) const
inline

This method does not throw.

Returns
A reference to the handled GObject.
template<class T>
T* Cgu::GobjHandle< T >::operator-> ( ) const
inline

This method does not throw.

Returns
A pointer to the handled GObject (or NULL if none is handled).
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.
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: