Glib学习笔记(四)
你将学到什么
使用GObject模拟实现接口
使用接口
- 首先按照学习笔记(一)定义一个普通的GObject类
- 使用
G_DEFINE_TYPE_WITH_CODE和G_IMPLEMENT_INTERFACE替代G_DEFINE_TYPE来实现类定义
static void viewer_file_editable_interface_init (ViewerEditableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_file_editable_interface_init))
- 实现接口初始化函数
viewer_file_editable_interface_init,接口内声明的每个虚函数指针都要被赋予实现
static void
viewer_file_editable_save (ViewerFile *self,
GError **error)
{
g_print ("File implementation of editable interface save method: %s.\n",
self->filename);
}
static void
viewer_file_editable_undo (ViewerFile *self,
guint n_steps)
{
g_print ("File implementation of editable interface undo method: %s.\n",
self->filename);
}
static void
viewer_file_editable_redo (ViewerFile *self,
guint n_steps)
{
g_print ("File implementation of editable interface redo method: %s.\n",
self->filename);
}
static void
viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
iface->save = viewer_file_editable_save;
iface->undo = viewer_file_editable_undo;
iface->redo = viewer_file_editable_redo;
}
static void
viewer_file_init (ViewerFile *self)
{
/* Instance variable initialisation code. */
}
扩展接口
如果一个接口的实现依赖另一个接口的实现,有点类似继承,那么首先按照上面的方式实现两个接口的定义,然后在定义GType的时候依次使用G_IMPLEMENT_INTERFACE添加两个接口的实现。
/* Make the ViewerEditableLossy interface require ViewerEditable interface. */
G_DEFINE_INTERFACE (ViewerEditableLossy, viewer_editable_lossy, VIEWER_TYPE_EDITABLE);
static void
viewer_file_editable_lossy_compress (ViewerEditableLossy *editable)
{
ViewerFile *self = VIEWER_FILE (editable);
g_print ("File implementation of lossy editable interface compress method: %s.\n",
self->filename);
}
static void
viewer_file_editable_lossy_interface_init (ViewerEditableLossyInterface *iface)
{
iface->compress = viewer_file_editable_lossy_compress;
}
static void
viewer_file_editable_save (ViewerEditable *editable,
GError **error)
{
ViewerFile *self = VIEWER_FILE (editable);
g_print ("File implementation of editable interface save method: %s.\n",
self->filename);
}
static void
viewer_file_editable_undo (ViewerEditable *editable,
guint n_steps)
{
ViewerFile *self = VIEWER_FILE (editable);
g_print ("File implementation of editable interface undo method: %s.\n",
self->filename);
}
static void
viewer_file_editable_redo (ViewerEditable *editable,
guint n_steps)
{
ViewerFile *self = VIEWER_FILE (editable);
g_print ("File implementation of editable interface redo method: %s.\n",
self->filename);
}
static void
viewer_file_editable_interface_init (ViewerEditableInterface *iface)
{
iface->save = viewer_file_editable_save;
iface->undo = viewer_file_editable_undo;
iface->redo = viewer_file_editable_redo;
}
static void
viewer_file_class_init (ViewerFileClass *klass)
{
/* Nothing here. */
}
static void
viewer_file_init (ViewerFile *self)
{
/* Instance variable initialisation code. */
}
G_DEFINE_TYPE_WITH_CODE (ViewerFile, viewer_file, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_file_editable_interface_init)
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE_LOSSY,
viewer_file_editable_lossy_interface_init))
接口属性
接口同样也可以拥有属性,不过是使用g_object_interface_install_property函数而不是像定义GType一样使用g_object_class_install_property函数来安装属性,如下所示:
static void
viewer_editable_default_init (ViewerEditableInterface *iface)
{
g_object_interface_install_property (iface,
g_param_spec_double ("autosave-frequency",
"Autosave frequency",
"Frequency (in per-seconds) to autosave backups of the editable content at Or zero to disable autosaves.",
0.0, /* minimum */
G_MAXDOUBLE, /* maximum */
0.0, /* default */
G_PARAM_READWRITE));
}
需要值得注意的一点是
重写接口方法
ViewerAudioFile继承自ViewerFile,两者都实现了ViewerEditable接口。ViewerAudioFile仅实现了ViewerEditable接口的其中一个方法,其他接口方法使用基类ViewerFile的实现,如下所示:
static void
viewer_audio_file_editable_save (ViewerEditable *editable,
GError **error)
{
ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable);
g_print ("Audio file implementation of editable interface save method.\n");
}
static void
viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
{
/* Override the implementation of save(). */
iface->save = viewer_audio_file_editable_save;
/*
* Leave iface->undo and ->redo alone, they are already set to the
* base class implementation.
*/
}
G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_audio_file_editable_interface_init))
static void
viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
/* Nothing here. */
}
static void
viewer_audio_file_init (ViewerAudioFile *self)
{
/* Nothing here. */
}
在接口的default_init函数里面使用g_type_interface_peek_parent函数可以获取基类的接口实现,可将其保存到全局变量中供其他函数使用。下面的例子中,ViewerAudioFile重写了接口的save函数,并在重写函数中直接调用基类ViewerFile接口的save函数实现。
static ViewerEditableInterface *viewer_editable_parent_interface = NULL;
static void
viewer_audio_file_editable_save (ViewerEditable *editable,
GError **error)
{
ViewerAudioFile *self = VIEWER_AUDIO_FILE (editable);
g_print ("Audio file implementation of editable interface save method.\n");
/* Now call the base implementation */
viewer_editable_parent_interface->save (editable, error);
}
static void
viewer_audio_file_editable_interface_init (ViewerEditableInterface *iface)
{
viewer_editable_parent_interface = g_type_interface_peek_parent (iface);
iface->save = viewer_audio_file_editable_save;
}
G_DEFINE_TYPE_WITH_CODE (ViewerAudioFile, viewer_audio_file, VIEWER_TYPE_FILE,
G_IMPLEMENT_INTERFACE (VIEWER_TYPE_EDITABLE,
viewer_audio_file_editable_interface_init))
static void
viewer_audio_file_class_init (ViewerAudioFileClass *klass)
{
/* Nothing here. */
}
static void
viewer_audio_file_init (ViewerAudioFile *self)
{
/* Nothing here. */
}
Glib学习笔记(四)的更多相关文章
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Typescript 学习笔记四:回忆ES5 中的类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
- muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制
目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...
- python3.4学习笔记(四) 3.x和2.x的区别,持续更新
python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...
- Go语言学习笔记四: 运算符
Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...
- 零拷贝详解 Java NIO学习笔记四(零拷贝详解)
转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...
随机推荐
- bootstrap+css进行页面布局
效果 用到了bootstrap中的表格css.圆形css.以及上一页下一页css. 布局页面,填充数据,实现js动态效果(比如点击下一页,上一页),逐步完善. 不仅仅要会使用bootstrap中的样式 ...
- 转载:利用UDEV服务解决RAC ASM存储设备名
利用UDEV服务解决RAC ASM存储设备名 本文转载自Maclean Liu :http://www.askmaclean.com/archives/utilize-udev-resolve-11g ...
- 实用webpack-dev-server
webpack-dev-server的作用 文件作出改动之后,保存,立即开始编译文件 编译后的文件是保存在内存中的,在项目文件夹中看不到编译后的文件 编译完成之后立即自动刷新浏览器 测试webpack ...
- Python时间日期函数讲解
所有日期.时间的api都在datetime模块内. 1. 日期输出格式化 datetime => string import datetime now = datetime.datetime.n ...
- const int *pi与int&nbs…
此质料是摘要:<<彻底搞定C 指针 >>,自己感觉比较有价值,现与大家分享. 1. 从const int i 说起 你知道我们声明一个变量时象这样int i :这个i是可能在它 ...
- 数据库与vs的连接
新建一个MFC基于对话框的项目后,更改属性, 其中需要将include(里面都是MySQL的头文件)lib是库文件,将.dll放入与.exe同级目录下,或放入系统里(c:\windows\system ...
- oracle数据库导入导出数据
导出命令 exp username/password@192.168.x.xx/orcl file='D:\20170126.dmp' log='D:\20170126.log' 导入命令 imp u ...
- SQLServer中的事物与锁
了解事务和锁 事务:保持逻辑数据一致性与可恢复性,必不可少的利器. 锁:多用户访问同一数据库资源时,对访问的先后次序权限管理的一种机制,没有他事务或许将会一塌糊涂,不能保证数据的安全正确读写. 死锁: ...
- Android selector中的item的顺序
在selector中,要将默认状态的item放在最后面,因为一旦前面的item满足匹配条件,后面的item就不会去匹配.因此,把默认状态的item放在前面的话,后面的item没有执行的机会
- Angular24 树形菜单 ???
待更新... 2018年5月21日15:17:47 参考博文01 参考博文02