《C编程.C以后》6.GObject

由于C编程语言不是在考虑面向对象编程的情况下创建的,因此它没有明确支持类,继承,多态和其他OO概念。它也没有自己的虚拟表,它可以在面向对象的语言中找到,比如C ++,Java和C#。因此,仅使用C语言特性和标准库来实现面向对象的编程范例可能并不容易。但是,它可以使用包含函数指针和数据的结构来完成,例如,或使用第三方库。

有许多第三方库旨在增加对C语言中面向对象编程的支持。其中最通用和广泛使用的是GObject系统,它是Glib的一部分。GObject系统带有自己的虚拟表。要使用GObject系统在C中创建对象,必须从GObject结构中对其进行子类化。

对象创建

在此示例中,将直接从GObject派生一个新对象。为简单起见,该对象名为MyObject

声明对象

要创建一个简单的不可派生(最终)对象,必须声明两个结构,实例。它们是使用宏声明的:

myobject.h中的/ * * / 
G_DECLARE_FINAL_TYPE  (MyObject , my_object , MY , OBJECT , GObject )

这声明了两个结构,MyObject和MyObjectClass。MyObject必须在C实现中定义,MyObjectClass已经由宏定义。

锅炉板代码

由于GObject系统只是第三方库,因此无法对C语言本身进行任何更改,因此创建新对象需要大量的样板代码。这主要由上面显示的宏处理。但是,还需要以下内容:

/ * in myobject.h * / 
#define MY_TYPE_OBJECT my_object_get_type()

宏定义了几个函数,即MY_OBJECT()和MY_OBJECT_CLASS(),用于转换,MY_IS_OBJECT()和MY_IS_OBJECT_CLASS()用于测试对象或类是否具有正确的类型,MY_OBJECT_GET_CLASS()用于从实例获取类结构。

定义对象

在使用之前,必须定义新创建的对象以及实例结构。

/ * in myobject.c * /

struct  _MyObject 
{ 
    GObject  parent_instance ;

    / *其他成员* / 
};

G_DEFINE_TYPE  (MyObject , my_object , G_TYPE_OBJECT )

静态函数

根据您的对象,可能会或可能不会定义一些静态函数。对于最小的对象,这些是必须的:

/ * in myobject.c * / 
static  void 
my_object_class_init  (MyObjectClass  * klass ) 
{ 
     / * code * / 
}

static  void 
my_object_init  (MyObject  * self )
{ 
     / * code * / 
}

构造函数

没有为C中的对象分配内存的内部方法。因此必须为新对象声明显式构造函数。

/ * in myobject.c * /

GObject  * 
my_object_new  (void )
{ 
     return  g_object_new  (MY_TYPE_OBJECT ,
                          0 ); 
}

对象用法

虽然使用自己的指针类型创建对象是完全有效的,但建议使用层次结构顶部对象的指针类型,即最远的基类。现在可以像这样使用新创建的对象:

/ *在main.c * /

/ *注意:GObject位于层次结构的顶部。* /

/ *声明和构造* / 
GObject  * myobj  =  my_object_new  (); 

/ * destruction * / 
g_object_unref  (myobj );

继承

概念

继承是最广泛使用和最有用的OO概念之一。它提供了一种通过将现有代码包装到对象中然后对其进行子类化来重用现有代码的有效方法。新类称为派生类。可以使用继承创建许多对象hieriarchies。继承也是抽象代码的最有效方法之一。

实施

在GObject的系统,继承可以通过子类来实现的GObject。由于C不提供继承关键字或运算符,因此通常通过将基本实例和基类分别声明为派生实例和派生类的成员来生成派生对象。在C代码中:

 
/ *派生对象实例* / struct _DerivedObject { / *基础实例是派生实例的成员* / BaseObject parent_instance ; };

相关文章: 《C编程.C以后》7.代码库

THE END
分享