Re: GObject instantiation hopelessly overcomplicated??

On Sun, 2004-07-18 at 16:43, Ryan McDougall wrote:
> The more I learn about what both type system and GObject do to create
> instances, the more I come to the conclusion that the way it works is
> way too complicated. I cannot think of a theoretical reason why fairly
> simple constructor semantics wouldn't work, so I'm pretty sure there
> must be a good practical reason ... however I'm not nearly experienced
> enough to know what that might be. Can someone explain it to me?
> Specifically:
> In class object instantiation, why does it bother copying memory from
> parent object to final when it will run the parent object's base_init on
> the final object anyways? base_init takes no parameter, so its kind of
> like a default constructor, no? Then anything that could be set with a
> memory copy could be set with base_init. The only think that *couldn't*
> be set is anything that was done to the class after base_init, which
> should hopefully only be class_init. So why should we have a class_init
> at all? Because class_init takes a parameter? Then why doesn't base_init
> take a parameter?

class_init is the convenient way of doing one-time initialization for
a class; not just establishing the default virtual function assignments,
but also properties, signals, etc.

base_init, while it *can* be hacked up to work like class_init
(static gboolean been_here = FALSE) is practical speaking, not useful
except for esoteric uses like child properties for GtkContainer.

In some sense, base_init is a hook to initialization of the derived
class from the parent class. Could you not do the copying and simply
leave everything to the base_init functions? Yes, but it would be
considerably less efficient and less convenient.

> Why does GObject implement its own constructor on top of the
> instance_init constructors? Worse of all it makes you manually chain up
> the parent constructors. If GObjects have their own constructors, then
> isn't instance_init basically redundant and useless? I know the GObject
> constructor is there to support properties, but couldn't we give
> instance_init a parameter and just be done with it?

The particular way that constructors are done is a little funky -
the parameters are pretty much useless. But the chaining up is
pretty much unavoidable since the constructors for all classes need
to be called.

I think if you work through the details of passing extra parameters
to instance_init you'll find that it would be unacceptably complicated.
It would make every init function call extra functions for something
only a tiny subset of classes need.

> As I've mentioned before, I'm writing a tutorial (the first part of
> which was posted to this list), so if you answer me, you will be
> answering a lot of other people too.
> Assuming that there are very good reasons for why the system is where it
> is, what advice should I give readers about which of the many init
> places is appropriate for what init code.

Set up your virtual functions, signals, and properties in class_init
Don't use base_init
Do fixed initialization in instance_init
Use a constructor only if you need to do one-time initialization after
 CONSTRUCT_ONLY parameters have been set. 

> This exercise has really made me appreciate just how much GTK+/GNOME
> need a proper high level language. Its interesting for me to learn about
> this stuff but 90% of application developers cannot be bother with this
> much minutiae.

GObject is very hard to reverse-engineer the use from reading the code.
It's a very flexible toolkit. It's probably a lot easier to figure out
from reading a library using it like GTK+.

(GTK+ is old, so if you read it's sources pay more attention to widgets
and objects added recently.)

Also, the other thing to keep in mind is that there really is a 
core usage of GObject and things like base_init, constructors, 
defining fundamental types are elaborations of that core usage.
You shouldn't introduce them to your readers until they have
a full understanding of the way that GObject normally is used.
(I'm not sure *I'm* advanced enough to learn about defining
new fundamental types yet ;-)


Attachment: signature.asc
Description: This is a digitally signed message part

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