GObject 参考手册:概念:GLib 动态类型系统:可实例化的类型:对象

Types which are registered with a class and are declared instantiable are what most closely resembles an object. Although GObjects (detailed in The GObject base class) are the most well known type of instantiable classed types, other kinds of similar objects used as the base of an inheritance hierarchy have been externally developed and they are all built on the fundamental features described below.
一个以类来注册,并声明为可实例化的类型常常称作对象。GObject(定义在 The GObject base class 中)是最有名的一个可实例化的类了,其他相似的类都继承于这个基本类来进行开发,他们都基于下面所述的基本特征。

For example, the code below shows how you could register such a fundamental object type in the type system:
下面的例子告诉你怎样才可以在类型系统中注册这样一个基本的类。

typedef struct {
  GObject parent;
  /* instance members */
  int field_a;
} MamanBar;
 
typedef struct {
  GObjectClass parent;
  /* class members */
  void (*do_action_public_virtual) (MamanBar *self, guint8 i);
 
  void (*do_action_public_pure_virtual) (MamanBar *self, guint8 i);
} MamanBarClass;
 
#define MAMAN_TYPE_BAR (maman_bar_get_type ())
 
GType 
maman_bar_get_type (void)
{
  static GType type = 0;
  if (type == 0) {
    static const GTypeInfo info = {
      sizeof (MamanBarClass),
      NULL,           /* base_init */
      NULL,           /* base_finalize */
      (GClassInitFunc) foo_class_init,
      NULL,           /* class_finalize */
      NULL,           /* class_data */
      sizeof (MamanBar),
      0,              /* n_preallocs */
      (GInstanceInitFunc) NULL /* instance_init */
    };
    type = g_type_register_static (G_TYPE_OBJECT,
                                   "BarType",
                                   &info, 0);
  }
  return type;
}

Upon the first call to maman_bar_get_type, the type named BarType will be registered in the type system as inheriting from the type G_TYPE_OBJECT.
在调用 maman_bar_get_type 之前,名为 BarType 的继承于 G_TYPE_OBJECT 的类将在类型系统中被注册。

Every object must define two structures: its class structure and its instance structure. All class structures must contain as first member a GTypeClass structure. All instance structures must contain as first member a GTypeInstance structure. The declaration of these C types, coming from gtype.h is shown below:
每个对象必须定义为两个结构:它的类结构和它的实例结构。所有的类结构的第一个成员必须是一个 GTypeClass 结构。所有的实例结构的第一个成员必须是 GTypeInstance 结构。下面显示了这些来自 gtype.h 的 C 类型的声明:

struct _GTypeClass
{
  GType g_type;
};
struct _GTypeInstance
{
  GTypeClass *g_class;
};

These constraints allow the type system to make sure that every object instance (identified by a pointer to the object’s instance structure) contains in its first bytes a pointer to the object’s class structure.
这些约束使得类型系统可以确保每个对象的实例(由指向该对象的实例结构的指针所标识) 的首字节指向该对象的类结构。

This relationship is best explained by an example: let’s take object B which inherits from object A:
这个关系可以由下面的例子来很好的解释:让我们来看看这个继承于对象A的对象B。

/* A definitions */
typedef struct {
  GTypeInstance parent;
  int field_a;
  int field_b;
} A;
typedef struct {
  GTypeClass parent_class;
  void (*method_a) (void);
  void (*method_b) (void);
} AClass;
 
/* B definitions. */
typedef struct {
  A parent;
  int field_c;
  int field_d;
} B;
typedef struct {
  AClass parent_class;
  void (*method_c) (void);
  void (*method_d) (void);
} BClass;

The C standard mandates that the first field of a C structure is stored starting in the first byte of the buffer used to hold the structure’s fields in memory. This means that the first field of an instance of an object B is A’s first field which in turn is GTypeInstance’s first field which in turn is g_class, a pointer to B’s class structure.
上述标准的C结构定义指示了这个C结构的第一个领域存储着类的结构。

Thanks to these simple conditions, it is possible to detect the type of every object instance by doing:
多亏了这些简单的条件,所以按下面的方法来就可能取得每个对象实例的类型:

B *b;
b->parent.parent.g_class->g_type

or, more quickly:
或者,更快的:

B *b;
((GTypeInstance*)b)->g_class->g_type

Initialization and Destruction
初始化和销毁

instantiation of these types can be done with g_type_create_instance:
实例化这些类型可以用 g_type_create_instance 来完成:

GTypeInstance* g_type_create_instance (GType          type);
void           g_type_free_instance   (GTypeInstance *instance);

g_type_create_instance will look up the type information structure associated to the type requested. Then, the instance size and instantiation policy (if the n_preallocs field is set to a non-zero value, the type system allocates the object’s instance structures in chunks rather than mallocing for every instance) declared by the user are used to get a buffer to hold the object’s instance structure.
g_type_create_instance 将查找请求的类型所关联的类型信息结构。然后由用户声明的实例的大小和实例化策略(如果 n_preallocs 设置为一个非零值,类型系统将会把对象的实例结构分配在内存块上,而不将依次分配每个实例)将得到一个缓存来保存对象实例的结构。

If this is the first instance of the object ever created, the type system must create a class structure: it allocates a buffer to hold the object’s class structure and initializes it. It first copies the parent’s class structure over this structure (if there is no parent, it initializes it to zero). It then invokes the base_class_initialization functions (GBaseInitFunc) from topmost fundamental object to bottom-most most derived object. The object’s class_init (GClassInitFunc) function is invoked afterwards to complete initialization of the class structure. Finally, the object’s interfaces are initialized (we will discuss interface initialization in more detail later).
如果实例是这个对象第一次创建的,那么类型系统必须创建一个类结构:它为其分配一个缓冲来保存这个对象的类结构并初始化它。它先用父类的类结构覆盖(如果没有父类,它将初始化为零),然后从最顶层的基本对象至最底层的对象调用 base_class_initialization 函数(GBaseInitFunc)。对象的类初始化函数(GClassInitFunc)被调用来完成类结构的初始化。最终,这个类的接口被初始化了(我们将在后面讨论接口初始化)。

Once the type system has a pointer to an initialized class structure, it sets the object’s instance class pointer to the object’s class structure and invokes the object’s instance_init (GInstanceInitFunc)functions, from top-most fundamental type to bottom-most most derived type.
一旦类型系统有一个指向初始化的类结构的指针,它设置对象的实例类指针指向对象的类结构并调用实例的初始化函数(GInstanceInitFunc),同样是从顶到底的顺序。

Object instance destruction through g_type_free_instance is very simple: the instance structure is returned to the instance pool if there is one and if this was the last living instance of the object, the class is destroyed.
对象的实例的销毁非常简单,通过 g_type_free_instance 即可:实例结构被返回到实例池中,如果这是对象的还有一个而且是最后一个存活的实例,那么这个类即被摧毁。

Class destruction (the concept of destruction is sometimes partly referred to as finalization in GType) is the symmetric process of the initialization: interfaces are destroyed first. Then, the most derived class_finalize (ClassFinalizeFunc) function is invoked. The base_class_finalize (GBaseFinalizeFunc) functions are Finally invoked from bottom-most most-derived type to top-most fundamental type and the class structure is freed.
类的销毁(关于这个销毁的另一概念是 GType 的终结)的过程与初始化的刚好对称:接口先被销毁。然后,调用类终结函数 class_finalize(ClassFinalizeFunc)。最终,将 base_class_finalize(GBaseFinalizeFunc)从底至顶的调用,直到类结构被销毁。

As many readers have now understood it, the base initialization/finalization process is very similar to the C++ constructor/destructor paradigm. The practical details are different though and it is important not to get confused by superficial similarities. GTypes have no instance destruction mechanism. It is the user’s responsibility to implement correct destruction semantics on top of the existing GType code. (this is what GObject does. See The GObject base class) Furthermore, C++ code equivalent to the base_init and class_init callbacks of GType is usually not needed because C++ cannot really create object types at runtime.
很多读者已经明白了,基本的初始化/终结化过程与C++的构造/析构函数非常相似。实际上细节是非常不同的,千万不要被表现的相似所迷惑。特别是,大多数用户开始认识到GType中并不存在类似于C++的构造器(这实际上是一个方法列表,由对象实例来调用所有有继承关系的方法),它必须建立在由GType 提供的特定的设施里。同样的,GType没有实例销毁机制。这是用户的职责,在现存的GType代码的顶端来实现正确的销毁(这就是GObject做的事情)。举个例子,如果从A继承的对象B被实例化了,GType将只调用对象B的instance_init回调函数,而C++运行环境将先调用对象A的构造器,接着再是对象B。事实上,C++代码与GType的base_init和class_init回调是等同的,不过C++常常是不需要这些的,因为它并不能真的在运行时创建类型。

The instantiation/finalization process can be summarized as follows:
关于实例化和终结化的处理过程可以归纳如下:

Invocation time Function Invoked Function’s parameters
First call to g_type_create_instance for target type type’s base_init function On the inheritance tree of classes from fundamental type to target type. base_init is invoked once for each class structure.
target type’s class_init function On target type’s class structure
interface initialization, see the section called “Interface Initialization”
Each call to g_type_create_instance for target type target type’s instance_init function On object’s instance
Last call to g_type_free_instance for target type interface destruction, see the section called “Interface Destruction”
target type’s class_finalize function On target type’s class structure
type’s base_finalize function On the inheritance tree of classes from fundamental type to target type. base_finalize is invoked once for each class structure.

Leave a Reply

Your email address will not be published. Required fields are marked *