Re: GObject constructors
- From: Dave Benson <daveb idealab com>
- To: "David Necas (Yeti)" <yeti physics muni cz>
- Cc: jacob kroon gmail com, gtk-list gnome org
- Subject: Re: GObject constructors
- Date: Thu, 10 Nov 2005 11:33:04 -0800
On Thu, Nov 10, 2005 at 08:21:46PM +0100, David Necas (Yeti) wrote:
> On Wed, Nov 09, 2005 at 06:43:17PM +0100, Jacob Kroon wrote:
> > I'm having problems with figuring out how to initialize my data properly.
> > My scenario is that I have:
> >
> > struct Parent {
> > GObject parent;
> > float *data;
> > }
> >
> > struct ParentClass {
> > GObjectClass parent;
> > int data_size;
> > }
> >
> > struct Child {
> > Parent parent;
> > }
> >
> > struct ChildClass {
> > ParentClass parent;
> > }
> >
> > Each subclass of Parent will use different, but fixed data sizes, so I
> > want Child to tell Parent how much
> > data it needs, and then let Parent initialize the data accordingly.
> >
> > The way I thought would work was this:
> >
> > 1. In child_class_init(*klass):
> > PARENT_CLASS(klass)->data_size = specific_size_for_this_subclass;
> > 2. In parent_instance_init(*obj)
> > klass = PARENT_GET_CLASS(obj);
> > obj->data = g_new(float, klass->data_size);
> >
> > but this wont work since PARENT_GET_CLASS(obj) in parent_instance_init()
> > returns the class for Parent,
> > not the subclass ChildClass, so data_size won't have the value I intended.
>
> I had similar problem and came to conclusion it's impossible
> to implement it this way, or at least it's against inheritance.
>
> However, you can keep 1. as it is and define a parent_instance_setup()
> method that contains the common code and call that from
> child constructor:
>
> 2a. parent_instance_setup(obj) {
> klass = PARENT_GET_CLASS(obj)
> obj->data = g_new(float, klass->data_size);
> }
>
> 2b. child_instance_init(obj) {
> parent_instance_setup(obj);
> }
actually, you can take advantage of the fact that
real prototype of GInstanceInitFunc is
typedef void (*GInstanceInitFunc) (GTypeInstance *instance,
gpointer g_class);
so, instead of using G_DEFINE_TYPE do it manually and use the
fuller prototype:
static void
parent_init (Parent *parent, ParentClass *real_class)
{
/* Real class will point to the concrete class instance,
ie the child's class. */
parent->data = g_new (float, real_class->size);
}
GType parent_get_type()
{
static GType io_type = 0;
if (!io_type)
{
static const GTypeInfo io_info =
{
sizeof(ParentClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gsk_io_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (Parent),
0, /* n_preallocs */
(GInstanceInitFunc) gsk_io_init,
NULL /* value_table */
};
io_type = g_type_register_static (G_TYPE_OBJECT, "Parent",
&io_info, G_TYPE_FLAG_ABSTRACT);
}
return io_type;
}
etc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]