• Glib学习笔记(四)


    你将学到什么

    使用GObject模拟实现接口

    使用接口

    • 首先按照学习笔记(一)定义一个普通的GObject类
    • 使用G_DEFINE_TYPE_WITH_CODEG_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.
    ",
               self->filename);
    }
    
    static void
    viewer_file_editable_undo (ViewerFile *self,
                               guint       n_steps)
    {
      g_print ("File implementation of editable interface undo method: %s.
    ",
               self->filename);
    }
    
    static void
    viewer_file_editable_redo (ViewerFile *self,
                               guint       n_steps)
    {
      g_print ("File implementation of editable interface redo method: %s.
    ",
               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.
    ",
               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.
    ",
               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.
    ",
               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.
    ",
               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.
    ");
    }
    
    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.
    ");
    
      /* 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. */
    }
    
  • 相关阅读:
    全球各国各类在轨与退役卫星数量与详细参数信息数据下载网站整理[转]
    土地覆盖土壤类型水体流域数据下载网站整理【转】
    Prometheus Operator配置钉钉告警
    Prometheus Operator自动发现功能修改 prometheus.yml文件
    prometheus operator 监控mysqlexporter
    prometheus operator 监控redisexporter
    Prometheus Operator 安装配置|最新版
    Linux 命令之 lsof 列出当前系统已打开的文件列表
    linux内核编译过程的最终总结版
    Linux内核裁剪的具体步骤
  • 原文地址:https://www.cnblogs.com/silvermagic/p/9087892.html
Copyright © 2020-2023  润新知