哈哈,大概应该查看的源代码,就是这些了。让我们回顾一下。
一、gobject类类型的注册。
1、_g_object_type_init函数是gobject类类型的注册函数。给出了GObjectClass(类结构体)、GObject(实例结构体)、g_object_base_class_init(类结构体的基本初始化函数)、g_object_do_class_init(类结构体的初始化函数),GTypeValueTable value_table,GTypeFundamentalInfo finfo,GTypeInfo info,g_value_register_transform_func(注册类型转换函数),等等,调用g_type_register_fundamental注册了基本类型。
2、g_object_base_class_init用于类结构体的基本初始化。
3、g_object_do_class_init用于类结构体初始化,主要作用:
a、定义全局 Quark,用于信号和数据存储。
b、设置 GObjectClass 的函数指针(如 constructor、set_property、get_property 等),这些是 GObject 的默认实现。
c、注册 "notify" 信号,用于属性变化通知。
d、接口检查:其中g_type_add_interface_check函数,用于添加接口检查函数,在这里,添加了一个object_interface_check_properties检查类是否正确实现了接口定义的属性。
4、g_object_init(实例结构体初始化函数)
二、gobject类类型创建实例的过程。
1、g_object_new系列函数,用于创建gobject类类型(及其子类型)的实例。这会涉及到类结构体的初始化,这意味着gobject类类型的注册过程中,向类型系统注册的各种函数会被调用执行。
2、g_object_new、g_object_new_with_properties、g_object_new_valist这些函数的区别基本在于,处理函数参数给出的属性的方式。
其内部逻辑基本上是:
a、类结构体获取:
g_type_class_peek_static:检查类是否已初始化(静态缓存)。
g_type_class_ref:如果未初始化,引用并初始化类(触发 viewer_file_class_init)。
b、属性验证:
find_pspec 和 g_object_new_is_valid_property 验证属性是否存在并有效。
这需要类和接口的属性已注册。
c、实例创建:
调用 g_object_new_internal 创建实例。
3、g_type_class_ref(重定向到 g_type_class_get),其内部执行:
a、父类初始化(递归)。
b、类初始化。若类未初始化,调用 type_class_init_Wm。
4、type_class_init_Wm函数是一个关键函数。其内部执行:
a、初始化类结构体:分配内存(class),设置初始状态为 BASE_CLASS_INIT。复制父类数据(如 GObjectClass)。
b、调用 base_init 函数:从顶级父类(如 GObject)到当前类(如 ViewerFile),依次调用 base_init(如 g_object_base_class_init)。状态:BASE_CLASS_INIT。
c、接口初始化(BASE_IFACE_INIT 阶段):
状态设置为 BASE_IFACE_INIT。
遍历类的接口条目(CLASSED_NODE_IFACES_ENTRIES)。
调用 type_iface_vtable_base_init_Wm 初始化接口的基类部分。
如果接口未定义基初始化,从父类继承(如 GObject 的接口)。
d、调用 class_init 函数:
状态设置为 CLASS_INIT。
调用 node->data->class.class_init(如 viewer_file_class_init)。
这是类特定的初始化逻辑。
e、接口初始化(IFACE_INIT 阶段):
状态设置为 IFACE_INIT。
再次遍历接口条目。
调用 type_iface_vtable_iface_init_Wm 初始化接口的具体实现。
f、完成初始化:状态设置为 INITIALIZED。
从type_class_init_Wm函数以上几步可以清楚的看到,类结构体、接口结构体都被初始化了2次。接口结构体初始化2次的函数分别是:type_iface_vtable_base_init_Wm 和 type_iface_vtable_iface_init_Wm。
5、type_iface_vtable_base_init_Wm 和 type_iface_vtable_iface_init_Wm的源代码表明,type_iface_vtable_base_init_Wm调用vtable(就是接口注册时GTypeInfo结构体中的初始化函数)中的基本初始化函数,就是_default_init,进行接口基本初始化。
type_iface_vtable_iface_init_Wm函数则调用iholder->info->interface_init函数进行接口初始化,这个函数是接口的实现类提供的。
最后,综上所述,根据type_class_init_Wm函数的内部逻辑,
创建gobject类的实例时,第一次会初始化类与接口,其类结构体与接口结构体的相关初始化过程:类的基本初始化(base_init)——接口基本初始化(_base_init(如果有)+_default_init)——类初始化(class_init)——接口初始化(_interface_init)。
因此,最后的结论:接口的_default_init先调用执行,类的class_init后执行。
所以,_default_init中可以安装属性规范,class_init中可以重写这些属性规范。