GObject对象系统(4) GObject基类



The previous chapter discussed the details of GLib's Dynamic Type System. The GObject library also contains an implementation for a base fundamental type named  GObject.
先前的章节讨论了GLib动态类型系统的细节,GObject还包含了一个名为GObject的基本类型的实现。
 

GObject is a fundamental classed instantiable type. It implements:

  • Memory management with reference counting

  • Construction/Destruction of instances

  • Generic per-object properties with set/get function pairs

  • Easy use of signals

GObject是基本的、可实例化的、拥有类结构的基本类型,它实现了:
* 引用计数的内存管理
* 实例的构造和析构
* 每个实例的属性设置/获取函数
* 易于使用的信号
 
All the GNOME libraries which use the GLib type system (like GTK+ and GStreamer) inherit from  GObject which is why it is important to understand the details of how it works.
所有的使用GLib类型系统的GNOME库(例如GTK+和GStreamer)都继承子GObject,所以理解GObject工作的细节是很重要的。
 

Object instantiation 对象实例化

The g_object_new family of functions can be used to instantiate any GType which inherits from the GObject base type. All these functions make sure the class and instance structures have been correctly initialized by GLib's type system and then invoke at one point or another the constructor class method which is used to:

  • Allocate and clear memory through g_type_create_instance,

  • Initialize the object's instance with the construction properties.

g_object_new家族函数可以用于实例化热河从GObject基类继承而来的GType类型,这些函数确保对象的类结构和实例结构能够被GLib类型系统正确地初始化,然后在某一个时间点调用类的构造方法来:
* 通过g_type_create_instance分配和清理内存
* 用构造属性初始化对象实例
 

Although one can expect all class and instance members (except the fields pointing to the parents) to be set to zero, some consider it good practice to explicitly set them.

Once all construction operations have been completed and constructor properties set, the constructed class method is called.

Objects which inherit from GObject are allowed to override this constructed class method. The example below shows how ViewerFile overrides the parent's construction process:

尽管开发者可以假设除了指向父类的域外其他所有类结构和实例结构的成员被设置为0,但在需要的时候开发者最好显式地设置它们。

一旦所有的构造操作已经完成并且构造属性已经被设置,类构造方法将被调用。

从GObject继承而来的对象可以重写类构造方法,以下代码展示了ViewerFile重写父类构造方法的过程:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#define VIEWER_TYPE_FILE viewer_file_get_type ()
G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)

struct _ViewerFile
{
  GObject parent_instance;

  /* instance members */
};

/* will create viewer_file_get_type and set viewer_file_parent_class */
G_DEFINE_TYPE (ViewerFile, viewer_file, G_TYPE_OBJECT)

static void
viewer_file_constructed (GObject *obj)
{
  /* update the object state depending on constructor properties */

  /* Always chain up to the parent constructed function to complete object
   * initialisation. */
  G_OBJECT_CLASS (viewer_file_parent_class)->constructed (obj);
}

static void
viewer_file_class_init (ViewerFileClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->constructed = viewer_file_constructed;
}

static void
viewer_file_init (ViewerFile *self)
{
  /* initialize the object */
}
 

 

If the user instantiates an object ViewerFile with:
如果开发者实例化一个叫ViewerFile的对象如下:
1
ViewerFile *file = g_object_new (VIEWER_TYPE_FILE, NULL);
 
If this is the first instantiation of such an object, the  viewer_file_class_init function will be invoked after any  viewer_file_base_class_init function. This will make sure the class structure of this new object is correctly initialized. Here,  viewer_file_class_init is expected to override the object's class methods and setup the class' own methods. In the example above, the  constructed method is the only overridden method: it is set to  viewer_file_constructed.
如果这是该对象的第一个实例,那么viewer_file_base_class_init函数域viewer_file_class_init函数将被依次调用。这确保了新对象的类结构被正确地初始化,viewer_file_class_init用来重写对象的类方法并设置自己的类方法,例如下面的例子中,constructed方法被重写为viewer_file_constructed。
 
Once  g_object_new has obtained a reference to an initialized class structure, it invokes its constructor method to create an instance of the new object, if the constructor has been overridden in  viewer_file_class_init. Overridden constructors must chain up to their parent’s constructor. In order to find the parent class and chain up to the parent class constructor, we can use the  viewer_file_parent_class pointer that has been set up for us by the  G_DEFINE_TYPE macro.
一旦g_object_new已经获取了一个已初始化的类结构的引用,它调用实例的构造函数去创建新对象的一个实例,构造函数可以在viewer_file_class_init中被重写。重写构造函数必须链起它们父类型的构造函数。为了获取父类结构和链起父类构造函数,我们可以使用在G_DEFINE_TYPE中定义的viewer_file_parent_class指针。
 
Finally, at one point or another,  g_object_constructor is invoked by the last constructor in the chain. This function allocates the object's instance buffer through  g_type_create_instance which means that the  instance_init function is invoked at this point if one was registered. After  instance_init returns, the object is fully initialized and should be ready to have its methods called by the user. When  g_type_create_instance returns,  g_object_constructor sets the construction properties (i.e. the properties which were given to  g_object_new) and returns to the user's constructor.
最后,g_object_constructor函数在构造函数调用链的最后被调用,该函数使用g_type_create_instance为对象实例分配内存,这时如果注册了instance_init函数,它就在这时被调用。在instance_init返回之后对象实例就被完全地初始化,可以通过方法调用来使用该对象了。当g_type_create_instance返回后,g_object_constructor为对象设置构造属性(通过g_object_new提供),之后返回给用户的构造函数。
 
The process described above might seem a bit complicated, but it can be summarized easily by the table below which lists the functions invoked by  g_object_new and their order of invocation:
上述流程可能有些繁琐,但可以很简单地总结为如下的表格,其中包含了g_object_new调用的函数以及它们地调用顺序:

 g_object_new

Invocation timeFunction invokedFunction's parametersRemark
First call to g_object_newfor target typetarget type's base_initfunctionOn the inheritance tree of classes from fundamental type to target type. base_init is invoked once for each class structure.Never used in practice. Unlikely you will need it.
target type's class_initfunctionOn target type's class structureHere, you should make sure to initialize or override class methods (that is, assign to each class' method its function pointer) and create the signals and the properties associated to your object.
interface's base_initfunctionOn interface's vtable 
interface's interface_initfunctionOn interface's vtable 
Each call to g_object_newfor target typetarget type's class constructormethod: GObjectClass->constructorOn object's instanceIf you need to handle construct properties in a custom way, or implement a singleton class, override the constructor method and make sure to chain up to the object's parent class before doing your own initialization. In doubt, do not override the constructor method.
type's instance_initfunctionOn the inheritance tree of classes from fundamental type to target type. the instance_initprovided for each type is invoked once for each instance structure.Provide an instance_init function to initialize your object before its construction properties are set. This is the preferred way to initialize a GObject instance. This function is equivalent to C++ constructors.
target type's class constructedmethod: GObjectClass->constructedOn object's instanceIf you need to perform object initialization steps after all construct properties have been set. This is the final step in the object initialization process, and is only called if the constructor method returned a new object instance (rather than, for example, an existing singleton).

 


Readers should feel concerned about one little twist in the order in which functions are invoked: while, technically, the class' constructor method is called  before the GType's  instance_init function (since  g_type_create_instance which calls  instance_init is called by  g_object_constructor which is the top-level class constructor method and to which users are expected to chain to), the user's code which runs in a user-provided constructor will always run  after GType's  instance_init function since the user-provided constructor  must (you've been warned) chain up  before doing anything useful.
读者对函数调用顺序的复杂性感到困惑:技术上而言,类的构造函数在GType的instance_init函数之前调用(因为调用instance_init的g_type_create_instance被最顶基类的构造函数g_object_constructor调用,开发者要求调用链上g_object_constructor)。在用户提供的构造函数中的代码总是在GType的instance_init函数之后运行,因为用户提供的构造汉主必须在作任何有用的是之前必须链式调用其他构造函数。

转载于:https://my.oschina.net/wsgalaxy/blog/3008509

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值