Any thoughts on this C++ smart pointer issue?

Jeff Franks jcfranks at tpg.com.au
Sun Nov 28 01:57:38 CET 2004


Brian (and other C++ enthusiast's),

There is one smart pointer issue that may come up when you see the first 
XFC development tarballs, so I thought I'd seek your preference now, if any.

Like Gtkmm, XFC uses a smart pointer (Xfc::Pointer<>) to manage GTK+ 
reference counting, but unlike Gtkmm, XFC doesn't enforce its usage. As 
things stand, in XFC it's equally valid to use either a smart pointer to 
manage all reference counting, or to manage reference counting yourself 
by calling  ref() and unref(). The beauty of Xfc::Pointer<> is that 
(internally) it knows if an object is a GObject or floating widget and 
handles its reference counting and sinking appropriately (there is no 
sink function in XFC).

Gtkmm forces the use of a smart pointer on all GObjects. For example, 
Gtkmm::Gtk::AccelGroup is derived from Gtkmm::Glib::Object and so it has 
an initial reference that must be cleared. For objects like these Gtkmm 
provides no public constructors. The default constructor is protected 
and is called by a public 'create' function that returns a smart 
pointer. Thus ensuring that a programmer doesn't forget to unreference 
the object. For example, you can only construct a Gtkmm::Gtk::AccelGroup 
with this create function:

static Glib::RefPtr<AccelGroup> create();

like this:

Glib::RefPtr<Gtk::AccelGroup> accel_group = Gtk::AccelGroup::create();
// use accel_group, it is unreferenced when it goes out of scope

My only concern with this approach is that the smart pointer is template 
class with some small overhead. The more you use smart pointers the 
bigger the overhead. Optimally, managing reference counting yourself is 
better but not as convenient, and there are times when this was 
preferred. So far I have taken the view that the programmer should have 
the choice. An experienced GTK+ programmer should feel quite comfortable 
calling ref() and unref() on an object. Whereas a new programmer that 
isn't sure can just use a smart pointer.

Compared with Gtkmm, you can create and use a Xfc::Gtk::AccelGroup 
either like this:

Pointer<Gtk::AccelGroup> accel_group = new Gtk::AccelGroup;
// use accel_group, it is unreferenced when it goes out of scope

or like this:

Gtk::AccelGroup *accel_group = new Gtk::AccelGroup;
// use accel_group
accel_group->unref();

The only disadvantage with this approach is that it requires the 
programmer to be aware of the class a new object derives from: 
Xfc::G::Object (never floating) or Xfc::Gtk::Object (floating). All the 
reference counting rules are identical to GTK+. So if you pass a 
floating object to an owner, or add a widget to a container, you don't 
need to worry about reference counting or smart pointers. If you pass a 
G::Object to an owner, like a Gtk::AccelGroup to a window, you have to 
explicitly unreference it after if you are not using a smart pointer. 
This only applies to object construction. All class methods that return 
a pointer to an object that must be unreferenced return as a smart pointer.

Jeff Franks.



More information about the Xfce4-dev mailing list