zoukankan      html  css  js  c++  java
  • 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. */
    }
    
  • 相关阅读:
    基于Furion的.NET5 WebApi开发框架
    由react的todolist想到的
    react第三节-基础概念梳理
    uniapp引入字体图标与uniapp传入事件对象与自定义参数
    (react+tsx)函数式组件传参问题
    关于git正确clone指定分支
    关于‘react-app-rewried 不是内部或外部命令’的深度解析
    flex下的多行对齐与预处理器中使用nth-child选择器
    webpack(2)--webapck自身的配置
    webpack解析(1)
  • 原文地址:https://www.cnblogs.com/silvermagic/p/9087892.html
Copyright © 2011-2022 走看看