Re: [gtk-list] gtk_foo_new() vs. gtk_foo_init()



On Fri, Apr 07, 2000 at 01:58:13PM -0700, Derek Simkowiak wrote:
> 
> 	When creating a new object, what kind of initialization should
> take place in _new(), and what kind of initialization should take place in
> _init()?
> 
> 	I was under the impression that the _new() function should do
> nothing more than 
> 
> GtkFoo*
> gtk_foo_new (void)
> {
>   return GTK_FOO (gtk_type_new (gtk_foo_get_type ()));
> }

I think that it is usually a bad idea to put too much complexity into
gtk_foo_new(), because it will seriously inconvenience anyone who
wants to derive new objects from foo.  If you have a bunch of code
hidden away in gtk_foo_new(), there will be no way for the author of a
derived class to properly initialize the "foo" part of their new
object.

A good way to deal with this is to add gtk_foo_construct(),
particularly when gtk_foo_new() needs to accept arguments.

In that case, you'd just say

void
gtk_foo_construct(GtkFoo *foo, gint foo_arg)
{
  /* do stuff */
}

GtkFoo*
gtk_foo_new(gint foo_arg)
{
  GtkFoo *foo = GTK_FOO(gtk_type_new(gtk_foo_get_type()));
  gtk_foo_construct(foo, foo_arg);
  return foo;
}

and when someone makes an object "bar" that is derived from foo,
they can call gtk_foo_construct() from inside of gtk_bar_construct().

> 	But then I looked at (an admittedly old copy of) Havoc's
> FrootTkxtBuffer source.  He does all of his initialization in _new(), and
> his _init() is blank.

I've certainly done that before, even though I know that it is Not A
Good Thing.  In some cases it just doesn't really matter, and laziness
tends to take hold... :-)

> 	I am creating a custom object (not a widget) which needs to set
> some values and call some _new() functions of its own.  I've put all that
> stuff into my _init() function.  Should that be put into _new() instead?
> Is the _init() reserved for X resources (GdkFonts/GdkWindows etc.) or some
> such thing?
>
> 	Is the _init() function even called on GtkObjects which are not
> widgets?  (Obviously, I assumed that they were.)

Yes, *_init() is always called for every GtkObject.

In summary, here is how all right-thinking people should do things:

*_init() should get your object into some sort of basic coherent
state: sometimes it is convenient to be able to create objects
directly via the gtk_type_new(gtk_foo_get_type()) mechanism, so
gtk_foo_init() should be used to insure that such an object isn't too
fscked up.  (Remember that the memory for new objects is automatically
zeroed, so you generally don't need to fill *_init() with foo->my_ptr
= NULL; foo->my_int = 0; stuff, unless you want to be very
explicit.)

*_construct() should be used to finish initializing your objects if
the initialization process requires arguments.

*_new() should never do anything other than call gtk_type_new() (which
called *_init()) and call *_construct(), if necessary.

I'm pretty sure that all of this is discussed in GGAD.  The section in
there on the object system is first-rate.

-JT




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