Re: Some feedback about using gtkmm in real projects.



On Thu, 12 Feb 2009 15:43:49 +0100
Paul Davis <paul linuxaudiosystems com> wrote:
> On Thu, Feb 12, 2009 at 3:34 PM, Germán Diago <germandiago gmail com>
> wrote: 
> > 1.- One of the things I think gets a lot in the way of the
> > programmer in gtkmm is the difference between
> > objects that use Glib::RefPtr and objects that don't. I think this
> > is an implementation detail and it should
> > not make any difference to use one type of object or another. I
> > think it should just be wrapped properly to hide
> > the difference.
> 
> The difference reflects issues at the GTK level. I believe it would
> need to changed there first.

I think it is more a matter of deciding what semantics you want for the
smart pointer, and what level of safety you want.  I have a GObject
handle class which can take both pure GObjects (not derived from
GInitiallyUnowned) and GObjects with floating references (those derived
from GInitiallyUnowned).  The constructor taking a pointer will see if
there is a floating reference, and if so sink it to take ownership, and
if not it will do nothing to take ownership. It therefore works in the
same way that std::shared_ptr does, irrespective of whether the
referenced object is, say, a pure GObject or derived from GtkWidget -
passing an object to it by pointer will automatically take ownership in
either case.

However, by doing so it shares all the dangers of manipulating object
lifetime with std::shared_ptr - it is only safe if a newly created
object is passed to the constructor taking a pointer (ideally the
creation of a new object to be referenced by shared_ptr takes the RIIA
form of 'shared_ptr<T> sh_ptr(new T);'.  If you pass the object to be
referenced to two different GObject handles by pointer then you
will end up with heap corruption.  In addition, if you pass a GObject
to it by pointer which is already owned by, say, a GTK+ container you
will also get heap corruption (unless you explicitly call
g_object_ref()).

Although unavoidable for automatic memory management when using raw
glib/gtk+, the glibmm/gtkmm approach can, and does, do things
differently.  Glib::RefPtr<> is much safer because the initial
Glib::RefPtr object referencing a Glib::Object object is only obtained
from factory functions and no raw pointer is ever exposed, so it is
impossible to have double ownership.

Since objects derived from Gtk::Widget are not intended to be copied
(see more below), it would be pointless to obtain them by factory
function.  They can be constructed as auto objects (on the stack) or
with operator new on the heap in the ordinary way, and would normally
be managed by their container.

It is therefore not an implementation detail as suggested by Germán,
but deliberate policy.  It is also something the user doesn't need to
puzzle over and frankly should not get in his way.  If an object can
only be obtained via a factory function returning it by Glib::RefPtr,
then use Glib::RefPtr; if it doesn't, then don't.  The mistake is in
thinking that Glib::RefPtr is a generic smart pointer.

Possibly the rationale behind Glib::RefPtr could be explained a bit
more in the documentation.

[snip]
> 4.- C++0x: Move semantics for all widgets.
> 
> not sure what this refers to.

Move constructors are constructors which can take an r value by
non-const reference (they are declared as T::T(T&&)). They are intended
to improve efficiency by enabling you to code a constructor which will
avoid an unnecessary copy when being initialised by a temporary.  They
invalidate the movee (which obviously doesn't matter for a temporary),
hence the "move" in the name.

Since objects derived from Gtk::Widget are not intended to be copied,
either through a copy constructor or an assignment operator, it would
probably help if Germán could explain his proposal further.  It may be
he was thinking of something different.

[snip]

Chris


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]