上节,我们讨论了类型的注册,这节,我们继续讨论类型的初始化
在C++等面向对象的编程语言中,当程序声明一个类型的时候,就已经知道了其类型的信息,比如它的大小,但是如果使用C来实现面向对象的这些特性,就需要作特殊的处理,对类进行单独的初始化.上一节中,类型的基本信息已经以TypeImpl保存在Hash表中,类的初始化是通过type_initialize函数完成的,这个函数并不长,函数的输入是表示类型信息的TypeImpl.
static void type_initialize(TypeImpl *ti)
{
TypeImpl *parent;
if (ti->class) {
return;
}
ti->class_size = type_class_get_size(ti);//获取类的大小
ti->instance_size = type_object_get_size(ti);//获取实例的大小
/* Any type with zero instance_size is implicitly abstract.
* This means interface types are all abstract.
*/
if (ti->instance_size == 0) {
ti->abstract = true;
}
ti->class = g_malloc0(ti->class_size);//为类分配大小
parent = type_get_parent(ti);//获取类型的父类
if (parent) {
type_initialize(parent);
GSList *e;
int i;
//判断父类的大小是否小于子类的大小
g_assert_cmpint(parent->class_size, <=, ti->class_size);
memcpy(ti->class, parent->class, parent->class_size);
ti->class->interfaces = NULL;
ti->class->properties = g_hash_table_new_full(
g_str_hash, g_str_equal, g_free, object_property_free);
for (e = parent->class->interfaces; e; e = e->next) {
InterfaceClass *iface = e->data;
ObjectClass *klass = OBJECT_CLASS(iface);
type_initialize_interface(ti, iface->interface_type, klass->type);//初始化父类的所有接口
}
for (i = 0; i < ti->num_interfaces; i++) {
TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
for (e = ti->class->interfaces; e; e = e->next) {
TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
//检查target_type是不是type的直接父类
if (type_is_ancestor(target_type, t)) {
break;
}
}
if (e) {
continue;
}
type_initialize_interface(ti, t, t);
}
} else {
ti->class->properties = g_hash_table_new_full(
g_str_hash, g_str_equal, g_free, object_property_free);
}
ti->class->type = ti;
while (parent) {
if (parent->class_base_init) {
parent->class_base_init(ti->class, ti->class_data);//依次调用父类和自己的初始化函数,和C++初始化一个对象时依次调用父类的构造函数一样。
}
parent = type_get_parent(parent);
}
if (ti->class_init) {
ti->class_init(ti->class, ti->class_data);
}
}
上面的代码显示type_initialize主要对父类和子类属性和接口进行初始化,并最后调用了初始化构造函数。