Re: Best practise inheritance



Now that I'm not on my phone, I can probably do a better job at
replying to this email.

On 21 March 2017 at 23:21, Emmanuele Bassi <ebassi gmail com> wrote:

On Tue, 21 Mar 2017 at 21:23, S. Jacobi <sjacobi mailueberfall de> wrote:

On Tue, 21 Mar 2017 20:53:04 +0000
Emmanuele Bassi <ebassi gmail com> wrote:


Also, do not store a private pointer in your instance structure, and
use the get_private_instance() function that the G_DEFINE_TYPE macro
creates for you.

So you say whenever I need access to the objects private data I should
call G_TYPE_INSTANCE_GET_PRIVATE, despite the mentioned overhead?


Nope. I said to use the get_instance_private() function generated for your
type by the G_DEFINE_TYPE macro, which uses pointer arithmetic and an offset
computed when the class is instantiated and it's constant for all instances.

Before GObject 2.38, the private data was allocated interleaved with
each instance data in the memory block; this meant that each GType has
to compute the offset for each ancestor type in the hierarchy. After
2.38, the private instance data is allocated as a single block, and
the offset for each ancestor class is constant and known once the type
is created (assuming you're using the G_DEFINE_TYPE macros and you're
not calling g_type_class_add_private() in an ancestor of your type;
for that case we still know the offset at class init time, which means
we always know the offset before you can instantiate a type). The
known offset allows us to retrieve a pointer to the private instance
data with simple, and fast, pointer arithmetic.

The G_DEFINE_TYPE_EXTENDED macro will create a
<your_type>_get_instance_private() static inline function that returns
a pointer to the private instance data. If you use
G_DEFINE_TYPE_WITH_PRIVATE, or G_DEFINE_TYPE_WITH_CODE (...
G_ADD_PRIVATE), GObject will do all the heavy lifting behind the
scenes for you — and it will ensure that any changes we make to
GObject will end up in your code with a simple rebuild.

Since getting the private instance data was "expensive" in the
beginning, the best practice was to use a private pointer inside the
instance data structure, at the cost of a slightly larger instance
structure size and at the cost of having a real instance structure
instead of just renaming `struct _GObject` to your type; now that
retrieving that data is fast, having that pointer is not necessary any
more (doing a pointer offset is actually faster than a pointer
redirection, on any modern architecture).

tl;dr: Always use G_DEFINE_TYPE and G_DECLARE_* macros to
automatically use best practices, and to avoid having to deal with the
innards of GType.

The GObject tutorial has a good introduction on how to define types
and how to use them.

Indeed. It took me a while to walk through it. However, the example
given in [3] has the comment /* Other members, including private data.
*/, which would contradict your opinion, or is at least a bit unclear,
because final and derivable types are handled a bit differently.

[3] https://developer.gnome.org/gobject/stable/howto-gobject-code.html

The example you're referring to is describing the "final type" case,
where the instance structure is already *private* to the source file.
This means you don't need a Private data structure at all — i.e. all
the instance data is private.

You should use private instance data structures if you're using
G_DECLARE_DERIVABLE_TYPE and you make your instance structure public,
in order to let other people subclass your type.

Ciao,
 Emmanuele.

-- 
https://www.bassi.io
[@] ebassi [@gmail.com]


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