本文是笔者整理网上资料加上一些自己实践的纪录,本文的主体内容转自如下文章:
源博客网址:http://garfileo.is-programmer.com/categories/6934/posts
以下是本文的所主要学习实践的其中a, b两个小题目的原文链接。
2. http://garfileo.is-programmer.com/2011/2/27/the-analog-of-classed-type-based-gobject.24798.html
其中1主要从宏观上阐述了GObject总体,帮助后来者确立学习GOject的信心。所以本文集中在2的理解上。
- 基于GObject实现一个自己的类,需要定义两个结构体,所谓“实例结构体”和“类结构体”
- 两个结构体名字实际上是不能随意取的,实例结构体的名字是${TypeName}, 那么类结构体的名字必须是${TypeName}Class
- 新定义的类型与GObject发生关系是通过 G_DEFINE_TYPE(TypeName, class_method_prefix, parent_type)。这个宏实际上是定义了一系列关键的函数和变量。就本节来说,pm_dlist_get_type(void) 具体实现就隐藏在这个宏中。
- pm_dlist_get_type(void) 将在 g_object_new 时被调用
- 在G_DEFINE_TYPE中声名了两个函数:pm_dlist_init(PMDList *self) 和 pm_dlist_class_init(PMDListClass *kclass);所以我们需要自己实现这两个函数,以实现类初始化和实例初始化。
由于原文成文于2011年,所以有些与目前官方不符的地方和一些实践中的谬误记录如下:
- 在测试程序中,作者特别提到g_type_init(),该API已经处于deprecate状态。官方文档已不推荐使用,经测试,确实可以直接去掉。
- 文中提到编译命令是 “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 |
|
较为熟悉 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 |
|