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 _______________________________________________ gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list