Appendix A. The RefPtr smartpointer

Glib::RefPtr is a smartpointer. Specifically, it is a reference-counting smartpointer. You might be familiar with std::auto_ptr<>, which is also a smartpointer, but Glib::RefPtr<> is much simpler, and more useful. We expect a future version of the C++ Standard Library to contain a reference-counting shared smartpointer, so a future version of gtkmm will probably use that instead.

Reference

A smartpointer acts much like a normal pointer. Here are a few examples.

Copying

You can copy RefPtrs, just like normal pointers. But unlike normal pointers, you don't need to worry about deleting the underlying instance

Glib::RefPtr<Gdk::Bitmap> refBitmap = Gdk::Bitmap::create(window,
data, width, height);
Glib::RefPtr<Gdk::Bitmap> refBitmap2 = refBitmap;

Of course this means that you can store RefPtrs in standard containers, such as std::vector or std::list.

std::list< Glib::RefPtr<Gdk::Pixmap> > listPixmaps;
Glib::RefPtr<Gdk::Pixmap> refPixmap = Gdk::Pixmap::create(window,
width, height, depth);
listPixmaps.push_back(refPixmap);

Dereferencing

You can dereference a smartpointer with the -> operator, to call the methods of the underlying instance, just like a normal pointer.

Glib::RefPtr<Gdk::Bitmap> refBitmap = Gdk::Bitmap::create(window,
data, width, height);
int depth = refBitmap->get_depth();

But unlike most smartpointers, you can't use the * operator to access the underlying instance.

Glib::RefPtr<Gdk::Bitmap> refBitmap = Gdk::Bitmap::create(window,
data, width, height);
Gdk::Bitmap* underlying = *refBitmap; //Syntax error - will not compile.

Casting

You can cast RefPtrs to base types, just like normal pointers.

Glib::RefPtr<Gtk::TreeStore> refStore = Gdk::TreeStore::create(columns);
Glib::RefPtr<Gtk::TreeModel> refModel = refStore;

This means that any method which takes a const Glib::RefPtr<BaseType> argument can also take a const Glib::RefPtr<DerivedType>. The cast is implicit, just as it would be for a normal pointer.

You can also cast to a derived type, but the syntax is a little different than with a normal pointer.

Glib::RefPtr<Gtk::TreeStore> refStore =
Glib::RefPtr<Gtk::TreeStore>::cast_dynamic(refModel);
Glib::RefPtr<Gtk::TreeStore> refStore2 =
Glib::RefPtr<Gtk::TreeStore>::cast_static(refModel);

Checking for null

Just like normal pointers, you can check whether a RefPtr points to anything.

Glib::RefPtr<Gtk::TreeModel> refModel = m_TreeView.get_model();
if(refModel)
{
  int cols_count = refModel->get_n_columns();
  ...
}

But unlike normal pointers, RefPtrs are automatically initialized to null so you don't need to remember to do that yourself.

Constness

The use of the const keyword in C++ is not always clear. You might not realise that const Something* declares a pointer to a const Something, The pointer can be changed, but not the Something that it points to.

Therefore, the RefPtr equivalent of Something* for a method parameter is const Glib::RefPtr<Something>&, and the equivalent of const Something* is const Glib::RefPtr<const Something>&.

The const ... & around both is just for efficiency, like using const std::string& instead of std::string for a method parameter to avoid unnecessary copying.