Re: [gnome-db]GdaConnectionPoolClass parent class



Ian D . Stewart wrote:

Ok.  Just to make sure we are all in the same page, object cleanup goes
something like this:

1) gda_object_class_finalize(klazz), which frees any resources not directly associated with the object (shutting down database collections, etc), and then
calls gda_object_class_finalize(klazz->parent)

Every class needs it's own finalize method if it contains dynamically allocated members, and you need not bother about finalize at all if it doesn't.


2) gda_object_free(obj), which unreferences the object, and

That's correct. Actually, every class has a _free method which then does nothing but call g_object_unref. The _free methods are written only to avoid type casting for the caller.


3) gda_object_delete(obj), which  deletes the object itself

There is no such a function IMHO, as well as for gda_object_destroy.



Here is my understanding of things:

Take a class GdaFoo, which has (in the most general case) a parent named XyzFather.

The GdaFoo structure has as its first member XyzFather father. Then come the additional structure members GdaFoo introduces. This structure is allocated for every instance of GdaFoo and carries the "properties" of the object instance (to talk in oo terms).

The GdaFooClass structure has as its first member XyzFatherClass father_class. Then come the additional structure members GdaFooClass introduces. This structure is allocated only once for a specific class and carries information that all classes share (e.g. pointers to signal handling routines).

When a class is registered, the GObject system calls all class_init functions of all ancestors of the class, so the complete GdaFooClass structure is initialized. Since they are called in the order from GObject to GdaFoo, every class can override initialization that has been done by it's ancestors. One of GObjectClass's structure members is "finalize", which is automatically called when the reference count of an object instance reaches zero.

When an instance is created (by g_object_new), all instance_init functions (like gda_foo_init) of all ancestors and the class itself are called, in the same order. So the whole GdaFoo structure gets initalized.

Every GObject maintains a reference count which can be incremented by g_object_ref and decremented by g_object_unref. GObjects should never be explicitely freed, but rather the reference cound should be decremented. Therefore, a function called gda_foo_free should in reality only call g_object_unref.

As soon as the reference count reaches zero, the _one_ finalize function that is pointed to from the "finalize" member of the GObjectClass part of the GdaFooClass structure is called.

If GdaFoo has no own finalize method (because it has no dynamically allocated instance members) this _is_ the finalize method of the parent (since gda_foo_class_init didn't overwrite it) and we don't have to bother with anything.

If GdaFoo has it's own finalize method, this is gda_foo_finalize, and the finalize method of the parent class would never be called. So we must call the parent's finalize method in gda_foo_finalize. The easiest way to achieve that is to store a pointer to the parent's class structure somewhere, and call parent->finalize (object), provided that parent is the pointer to the XyzFatherClass structure. As only a single instance of XyzFatherClass exists, it's not _that_ important where to store that pointer. I have decided to store it in the GdaFooClass structure rather than in a global variable.

Therefore, if GdaFoo contains dynamically allocated elements, we have to have
struct GdaFooClass
{
        XyzFatherClass  father_class;
        XyzFatherClass *parent;
        [other members, like signal handlers]
}

I hope I have explained understandable, and I hope I have a correct view of the things. If not, I have a least confused you completely ;-)

Thanks,
--
Reinhard Müller
BYTEWISE Software GmbH
A-6890 Lustenau, Enga 2
Tel +43 (5577) 89877-0
Fax +43 (5577) 89877-66
http://www.bytewise.at





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