GObject学习(二)

本文详细介绍了如何使用GObject库在C语言中模拟面向对象的私有属性,通过G_DEFINE_TYPE_WITH_CODE和G_ADD_PRIVATE宏实现数据隐藏。讨论了非类类型数据和GObject子类对象属性的隐藏方法,强调了数据隐藏对于代码维护和减少依赖的重要性。
摘要由CSDN通过智能技术生成

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

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

以下是本文的所主要学习实践的其中c这个小题目的原文链接。
http://garfileo.is-programmer.com/2011/2/28/data-hiden.24848.html

本节主要是体会数据隐藏的意义和方式方法。

  1. 头文件之包含了实例结构体和类结构体的声明,不仅简洁,而且有效对开发者屏蔽了所谓的细节信息,但是更重要的是其他开发者在引用了pm-dlist.h之后,只要该头文件不变,即便具体的实现变化,哪怕是在数据结构中增减变量,都不会引发其他程序的重新编译。当然前提是pm-dlist自己形成了动态链接库。为此笔者做了简单的实验:
$ gcc pm-dlist.c $(pkg-config --cflags --libs gobject-2.0) -fPIC -shared libpm-dlist.so
$ gcc main.c $(pkg-config --cflags --libs gobject-2.0) -L./ -lpm-dlist -o test
$ ./test

这样可以复原原作者的实验结果。唯一区别是,没有将所有文件编译在一起。
然后修改pm-dlist.c,比如在PMDListPrivate中添加变量char label。此时,只需要再次重新编译libpm-dlist.so然后再运行test就可以反映出变化。

  1. 进一步思考的在c++中,private关键字,名义上也是为了实现“数据隐藏”。但是这种隐藏如果明确写在头文件中,那么实际上也没有对别的开发者进行屏蔽。虽然有访问限制,但是,对调用者并非“悄无声息”。特别是,如果出现1所述场景,还会引发问题。针对此,所以就有了所谓“PIMPL idiom”,具体可参考下列链接:
    (1). https://stackoverflow.com/questions/60570/why-should-the-pimpl-idiom-be-used
    (2). https://cpppatterns.com/patterns/pimpl.html

  2. 作者成文于2011年,所以有些代码稍显老旧,除了GObject学习(一)中所说,本文亦有部分,所以说明如下:
    (1). G_TYPE_INSTANCE_GET_PRIVATE已经处于deprecated状态。

G_TYPE_INSTANCE_GET_PRIVATE has been deprecated since version 2.58 and should not be used in newly-written code.Use G_ADD_PRIVATE and the generated your_type_get_instance_private() function instead

从中可以看到,目前官方推荐使用的宏是G_ADD_PRIVATE。

A convenience macro to ease adding private data to instances of a new type in the C section of G_DEFINE_TYPE_WITH_CODE() or G_DEFINE_ABSTRACT_TYPE_WITH_CODE().

笔者采用配合使用的宏就是G_DEFINE_TYPE_WITH_CODE(),注意这个宏是用来定义新“类型”的,其对标的对象是第一节提到的G_DEFINE_TYPE()

G_DEFINE_TYPE_WITH_CODE (PMDList, pm_dlist, G_TYPE_OBJECT, {
   G_ADD_PRIVATE(PMDList); \
        g_printf("This is in PMDList type add private, %d\n", PMDList_private_offset);});

进一步,就不需要再在_class_init中添加g_type_class_add_private (klass, sizeof (PMDListPrivate));这个函数了。

  1. G_DEFINE_TYPE()和G_DEFINE_TYPE_WITH_CODE()
#define G_DEFINE_TYPE(TN, t_n, T_P)             G_DEFINE_TYPE_EXTENDED (TN, t_n, T_P, 0, {
   })
#define G_DEFINE_TYPE_EXTENDED(TN, t_n, T_P, _f_, _C_)      _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, _f_
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值