GObject学习(一)

本文介绍了如何使用GObject库在C语言中实现面向对象编程的数据封装,特别是通过GObject实现一个双向链表类。文章讨论了GObject的结构、好处,以及如何定义和初始化类结构体。通过G_DEFINE_TYPE宏,实现了类型注册,允许GObject库识别自定义数据类型。此外,还强调了G_TYPE_OBJECT和g_object_new函数在对象实例化中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 本文是笔者整理网上资料加上一些自己实践的纪录,本文的主体内容转自如下文章:

源博客网址:http://garfileo.is-programmer.com/categories/6934/posts

以下是本文的所主要学习实践的其中a, b两个小题目的原文链接。

1. http://garfileo.is-programmer.com/2011/2/25/we-should-believe-gobject-is-useful-and-simple.24746.html

2. http://garfileo.is-programmer.com/2011/2/27/the-analog-of-classed-type-based-gobject.24798.html

其中1主要从宏观上阐述了GObject总体,帮助后来者确立学习GOject的信心。所以本文集中在2的理解上。

  1. 基于GObject实现一个自己的类,需要定义两个结构体,所谓“实例结构体”“类结构体”
  2. 两个结构体名字实际上是不能随意取的,实例结构体的名字是${TypeName}, 那么类结构体的名字必须是${TypeName}Class
  3. 新定义的类型与GObject发生关系是通过 G_DEFINE_TYPE(TypeName, class_method_prefix, parent_type)。这个宏实际上是定义了一系列关键的函数和变量。就本节来说,pm_dlist_get_type(void) 具体实现就隐藏在这个宏中。
  4. pm_dlist_get_type(void) 将在 g_object_new 时被调用
  5. 在G_DEFINE_TYPE中声名了两个函数:pm_dlist_init(PMDList *self) 和 pm_dlist_class_init(PMDListClass *kclass);所以我们需要自己实现这两个函数,以实现类初始化和实例初始化。

由于原文成文于2011年,所以有些与目前官方不符的地方和一些实践中的谬误记录如下:

  1. 在测试程序中,作者特别提到g_type_init(),该API已经处于deprecate状态。官方文档已不推荐使用,经测试,确实可以直接去掉。
  2. 文中提到编译命令是 “gcc $(pkg-config --cflags --libs gobject-2.0) pmd-dlist.c main.c -o test” 其实应当改为 “gcc pmd-dlist.c main.c $(pkg-config --cflags --libs gobject-2.0) -o test”

 

以下是作者原文转载,放在此处纯属是为了自己方便,并且防止原文地址丢失。


使用 GObject 库模拟类的数据封装形式 

事实上,有关 GObject 库的学习与使用,GObject 库参考手册提供了一份简短且过于晦涩的指南。如果你能够理解它,那么完全可以无视这篇以及后续的几篇文章。倘若没有明白那份指南,那么建议最好能克制一下,先不要急于去做文档 [1] 中所列举那些探索,谨记 Knuth 所说的,过早优化是诸恶之源。

这篇文档主要讲述如何使用 GObject 库来模拟面向对象程序设计的最基本的要素,即基于类的数据封装,所采用的具体示例是一个双向链表的设计。

从一个双向链表的数据结构开始

对于双向链表这种数据结构,即便是 C 语言的初学者也不难创建一个名为 double-list.h 的头文件并写出以下代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

/* file name: double-list.h */

 

#ifndef DOUBLE_LIST_H

#define DOUBLE_LIST_H

 

struct double_list_node {

        struct doule_list_node *prev;

        struct double_list_node *next;

        void *data;

};

 

struct double_list {

        struct double_list_node *head;

        struct double_list_node *tail;

};

 

#endif

较为熟悉 C 语言的人自然不屑于写出上面那种新手级别的代码,他们通常使用 typedef 关键字去定义数据类型,并且将 double_list 简写为 dlist,以避免重复的去写 "struct double_list_xxxxx" 这样的代码,此外还使用了 Pascal 命名惯例,即单词首字母大写[2],具体如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

/* file name: dlist.h(版本 2)*/

 

#ifndef DLIST_H

#define DLIST_H

 

typedef struct _DListNode DListNode;

struct  _DListNode {

        DListNode *prev;

        DListNode *next;

        void *data;

};

 

typedef struct _DList DList;

struct  _DList {

        DListNode *head;

        DListNod

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值