GLib类型系统

来源:互联网 发布:江苏警官学院知乎 编辑:程序博客网 时间:2024/05/16 13:46

介绍怎么样在GObject类型系统中注册一个类型。

注册类型

 

g_type_register_static用来向类型系统注册新的类型。所有的类型都需要定义以下信息,它们都以函数指针的方式包含在一个GTypeInfo对象中,并且作为g_type_register_static的参数提供给类型系统:

  • class size: class_size .
  • class initialization functions (C++ constructor): base_init and class_init .
  • class destruction functions (C++ destructor): base_finalize and class_finalize .
  • instance size (C++ parameter to new): instance_size .
  • instantiation policy (C++ type of new operator): n_preallocs.
  • copy functions (C++ copy operators): value_table .
  • type characteristic flags: GTypeFlags .

每个类型都必须定义两个结构:类结构与实例结构。类结构的第一个成员必须是GTypeClass类型,而实例结构的第一个成员必须是GTypeInstance 类型。类结构存放的是一个类型的公共信息,类似C++中的成员函数和静态成员变量;而实例结构存放的是一个类型的各个实例所特有的信息,在类型系统中具有多个每个实例的实例结构都可以不同,类似C++中的普通成员变量。

下面的例子告诉我们怎样在类型系统中注册一个类并用g_object_new获得这个类的一个实例:


类型与实例的初始化

上面提到了注册系统时需要的三个初始化函数,instance_init提供了实例结构(例如MamanBar)的初始化,而base_init和class_init提供了类结构(例如MamanBarClass)的初始化。那么base_init和class_init有什么区别呢?当存在继承关系时,直接拷贝不能完整地拷贝信息时,就需要base_init。例如下面的代码将字符串的初始化放在base_init中。

 

typedef struct {  GObjectClass parent_class;  gint         static_integer;  gchar       *dynamic_string;} TypeAClass;static void type_a_base_init (TypeAClass *class){  class->dynamic_string = g_strdup ("some string");}static void type_a_base_finalize (TypeAClass *class){  g_free (class->dynamic_string);}static void type_a_class_init (TypeAClass *class){  class->static_integer = 42;}typedef struct {  TypeAClass   parent_class;  gfloat       static_float;  GString     *dynamic_gstring;} TypeBClass;static void type_b_base_init (TypeBClass *class){  class->dynamic_gstring = g_string_new ("some other string");}static void type_b_base_finalize (TypeBClass *class){  g_string_free (class->dynamic_gstring);}static void type_b_class_init (TypeBClass *class){  class->static_float = 3.1415926;}

 

继承关系

如果要让类型B继承类型A,只要使A的类结构和实例结构分别作为B的类结构和实例结构的第一个成员。

 

 

 

原创粉丝点击