• Glib学习笔记(二)


    你将学到什么

    • 如何实现Object的构造函数和析构函数
    • 如何在条件检测不允许的情况下终止对象创建

    Object的构造函数

    对象的构造函数是不允许失败,如果你需要一个允许失败的GObject构造函数,使用GIO库提供的GInitableGAsynclnitable接口(文章最后会有个例子说明)

    G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
    
    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
    }
    
    static void
    viewer_file_init (ViewerFile *self)
    {
      ViewerFilePrivate *priv = viewer_file_get_instance_private (self);
    
      /* initialize all public and private members to reasonable default values.
       * They are all automatically initialized to 0 to begin with. */
    }
    

    如果你需要指定构造属性(G_PARAM_CONSTRUCT_ONLY),首先在class_init()函数里面安装这些属性,然后重写类的set_property()get_property()方法,实现属性的获取和设置,如下:

    enum
    {
      PROP_FILENAME = 1,
      PROP_ZOOM_LEVEL,
      N_PROPERTIES
    };
    
    static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
    
    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
      GObjectClass *object_class = G_OBJECT_CLASS (klass);
    
      object_class->set_property = viewer_file_set_property;
      object_class->get_property = viewer_file_get_property;
    
      obj_properties[PROP_FILENAME] =
        g_param_spec_string ("filename",
                             "Filename",
                             "Name of the file to load and display from.",
                             NULL  /* default value */,
                             G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
    
      obj_properties[PROP_ZOOM_LEVEL] =
        g_param_spec_uint ("zoom-level",
                           "Zoom level",
                           "Zoom level to view the file at.",
                           0  /* minimum value */,
                           10 /* maximum value */,
                           2  /* default value */,
                           G_PARAM_READWRITE));
    
      g_object_class_install_properties (object_class,
                                         N_PROPERTIES,
                                         obj_properties);
    }
    

    Object的析构函数

    Object对象在引用计数为0后会依次调用disposefinalize函数完成析构,如下:

    struct _ViewerFilePrivate
    {
      gchar *filename;
      guint zoom_level;
    
      GInputStream *input_stream;
    };
    
    G_DEFINE_TYPE_WITH_PRIVATE (ViewerFile, viewer_file, G_TYPE_OBJECT)
    
    static void
    viewer_file_dispose (GObject *gobject)
    {
      ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
    
      /* In dispose(), you are supposed to free all types referenced from this
       * object which might themselves hold a reference to self. Generally,
       * the most simple solution is to unref all members on which you own a 
       * reference.
       */
    
      /* dispose() might be called multiple times, so we must guard against
       * calling g_object_unref() on an invalid GObject by setting the member
       * NULL; g_clear_object() does this for us.
       */
      g_clear_object (&priv->input_stream);
    
      /* Always chain up to the parent class; there is no need to check if
       * the parent class implements the dispose() virtual function: it is
       * always guaranteed to do so
       */
      G_OBJECT_CLASS (viewer_file_parent_class)->dispose (gobject);
    }
    
    static void
    viewer_file_finalize (GObject *gobject)
    {
      ViewerFilePrivate *priv = viewer_file_get_instance_private (VIEWER_FILE (gobject));
    
      g_free (priv->filename);
    
      /* Always chain up to the parent class; as with dispose(), finalize()
       * is guaranteed to exist on the parent's class virtual function table
       */
      G_OBJECT_CLASS (viewer_file_parent_class)->finalize (gobject);
    }
    
    static void
    viewer_file_class_init (ViewerFileClass *klass)
    {
      GObjectClass *object_class = G_OBJECT_CLASS (klass);
    
      object_class->dispose = viewer_file_dispose;
      object_class->finalize = viewer_file_finalize;
    }
    
    static void
    viewer_file_init (ViewerFile *self);
    {
      ViewerFilePrivate *priv = viewer_file_get_instance_private (self);
    
      priv->input_stream = g_object_new (VIEWER_TYPE_INPUT_STREAM, NULL);
      priv->filename = /* would be set as a property */;
    }
    

    使用GInitable接口

    通过G_DEFINE_TYPE_WITH_CODE宏替代G_DEFINE_TYPE来定义GType,然后使用G_IMPLEMENT_INTERFACE创建一个GInitable对象(GType类型为G_TYPE_INITABLE),并实现接口的init函数(接口的定义和实现参考笔记四),这样在init实现函数中,我们可以对对象创建预置环境进行检测,如果不条件不符合,返回False即可终止对象创建

    G_DEFINE_TYPE_WITH_CODE(SpiceUsbDeviceManager,
        spice_usb_device_manager,
        G_TYPE_OBJECT,
        G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, spice_usb_device_manager_initable_iface_init));
    
        static void spice_usb_device_manager_initable_iface_init(GInitableIface *iface)
    {
        iface->init = spice_usb_device_manager_initable_init;
    }
    
    static gboolean spice_usb_device_manager_initable_init(GInitable  *initable, GCancellable *cancellable, GError **err)
    {
        /* 此处代码省略 */
        return FALSE;
    }
    
  • 相关阅读:
    吴裕雄--天生自然 PYTHON数据分析:糖尿病视网膜病变数据分析(完整版)
    吴裕雄--天生自然 PYTHON数据分析:糖尿病视网膜病变数据分析(续六)
    吴裕雄--天生自然 PYTHON数据分析:糖尿病视网膜病变数据分析(续五)
    吴裕雄--天生自然 PYTHON数据分析:糖尿病视网膜病变数据分析(续四)
    MaxCompute安全管理指南-案例篇
    MaxCompute安全管理指南-基础篇
    发光的二次元——克拉克拉上云实践
    使用应用程序(Java/Python)访问MaxCompute Lightning进行数据开发
    Sentinel 发布里程碑版本,添加集群流控功能
    高效开发 Dubbo?用 Spring Boot 可得劲!
  • 原文地址:https://www.cnblogs.com/silvermagic/p/9087888.html
Copyright © 2020-2023  润新知