`
cloverprince
  • 浏览: 129832 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

GObject 03: An Instantiatable Class

阅读更多
Most of the time classes are instantiatable.  It can create "instances", which have their own data and share common methods of the class.

So a CLASS is shared by many INSTANCEs.

In GObject, we need two structs.  One for the class and one for the instance.

/* A fundamental type.  Instantiatable. */

#include <stdio.h>
#include <glib-object.h>

typedef struct {
    GTypeClass something_as_boilerplate;
} myclass_t;

int a_class_member_of_myclass;

typedef struct {
    GTypeInstance something_as_boilerplate; int an_instance_member;
} myinstance_t;

void my_class_method() {
    printf("The class member is %d\n", a_class_member_of_myclass);
}

void my_instance_method(myinstance_t *instance, int a_parameter) {
    printf("The member is %d\n",instance->an_instance_member);
    printf("The parameter is %d\n",a_parameter);
}

void my_class_init_func(myclass_t* klass, gpointer data) {
    printf("my_class_init_func called!\n");
    a_class_member_of_myclass = 42;
}

void my_instance_init_func(myinstance_t *instance, gpointer data) {
    printf("my_instance_init_func called!\n");
    instance->an_instance_member = 65;
}

int main() {
    g_type_init();

    GTypeInfo my_type_info = {
        sizeof(myclass_t),  //guint16                class_size;

        NULL,               //GBaseInitFunc          base_init;
        NULL,               //GBaseFinalizeFunc      base_finalize;

        /* classed types, instantiated types */
        (GClassInitFunc)my_class_init_func, //GClassInitFunc         class_init;
        NULL,               //GClassFinalizeFunc     class_finalize;
        NULL,               //gconstpointer          class_data;

        /* instantiated types */
        sizeof(myinstance_t),//guint16               instance_size;
        0,                  //guint16                n_preallocs;
        (GInstanceInitFunc)my_instance_init_func, //GInstanceInitFunc      instance_init;

        /* value handling */
        NULL,               //const GTypeValueTable *value_table;
    };

    GTypeFundamentalInfo my_fundamental_info = {
        G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE
    };

    GType my_type_id = g_type_register_fundamental(
            g_type_fundamental_next(),
            "MyInstantiatableFundamentalType",
            &my_type_info,
            &my_fundamental_info,
            0
            );

    printf("%d\n",my_type_id);
    printf("%s\n",g_type_name(my_type_id));

    myinstance_t *instance = (myinstance_t*)g_type_create_instance(my_type_id);
    
    my_instance_method(instance,78);
    my_class_method();

    printf("Is instance of class? %s\n",
            G_TYPE_CHECK_INSTANCE_TYPE(instance, my_type_id)?"yes":"no");
    printf("Is instance of class? %s\n",
            G_TYPE_CHECK_INSTANCE_TYPE(instance, G_TYPE_INT)?"yes":"no");

    return 0;
}


And focus in here:
typedef struct {
    GTypeClass something_as_boilerplate;
} myclass_t;

int a_class_member_of_myclass;

typedef struct {
    GTypeInstance something_as_boilerplate;
    int an_instance_member;
} myinstance_t;


Q: What are the something_as_boilerplate things?
A: As every other classes in GObject, all class structs start with a GTypeClass field and all instance structs start with a GTypeInstance field.

Q: What do they contain?
A: GTypeClass contains a GType which shows its type.  GTypeInstance contains a pointer to its class struct so every instance knows its class.  See the source code to make sure.

Q: Where are their members/fields?
A: Non-static members (such as an_instance_member) are in the instance struct, after the GTypeInstace.  Static members (such as a_class_member_of_myclass) are usually global and are usually not in the class struct(see the previous article).

Q: How do you figure out if it is a member or a global variable?
A: You say "let it be a member" and it is a member.  The concepts "object-oriented programming", "class", "instance" and "member" are all man-made so it is a member if you treat it like a member.


And the functions:
void my_class_method() {
    printf("The class member is %d\n", a_class_member_of_myclass);
}

void my_instance_method(myinstance_t *instance, int a_parameter) {
    printf("The member is %d\n",instance->an_instance_member);
    printf("The parameter is %d\n",a_parameter);
}


Q: What are methods like?
A: Methods are simply functions.  Non-static methods always take a pointer to an instance struct as their first parameter.  Static methods are ordinary functions.

Q: How do you figure out if it is a member or a global variable?
A: You say "let it be a method" and it is a method.  The concept "method" is man-made so it is a method if you treat it like a method.


Now we ask GLib to recognize my class as a type.
Code from the main() function:
    GTypeInfo my_type_info = {
        sizeof(myclass_t),  //guint16                class_size;

        NULL,               //GBaseInitFunc          base_init;
        NULL,               //GBaseFinalizeFunc      base_finalize;

        /* classed types, instantiated types */
        (GClassInitFunc)my_class_init_func, //GClassInitFunc         class_init;
        NULL,               //GClassFinalizeFunc     class_finalize;
        NULL,               //gconstpointer          class_data;

        /* instantiated types */
        sizeof(myinstance_t),//guint16               instance_size;
        0,                  //guint16                n_preallocs;
        (GInstanceInitFunc)my_instance_init_func, //GInstanceInitFunc      instance_init;

        /* value handling */
        NULL,               //const GTypeValueTable *value_table;
    };

    GTypeFundamentalInfo my_fundamental_info = {
        G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE
    };

    GType my_type_id = g_type_register_fundamental(
            g_type_fundamental_next(),
            "MyInstantiatableFundamentalType",
            &my_type_info,
            &my_fundamental_info,
            0
            );


Again we use the g_type_register_fundamental() function to make the library think myclass is a class whose instance is myinstance.

We provide one GTypeInfo struct.  class_size and instance_size are filled so that the library can automatically malloc a myclass_t struct and some myinstance_t structs.  class_init and instance_init are also provided so that the library can help me initialize the class/instance struct when they are created.

In GTypeFundamentalInfo, mark my class as CLASSED and INSTANTIATABLE.

Register it with g_type_register_fundamental and then it becomes a type.


And the init functions:
void my_class_init_func(myclass_t* klass, gpointer data) {
    printf("my_class_init_func called!\n");
    a_class_member_of_myclass = 42;
}

void my_instance_init_func(myinstance_t *instance, gpointer data) {
    printf("my_instance_init_func called!\n");
    instance->an_instance_member = 65;
}

They initialize the class and the instance, respectively on creating.  You can omit them if they are not necessary.


Now the main() function:
    printf("%d\n",my_type_id);
    printf("%s\n",g_type_name(my_type_id));

    myinstance_t *instance = (myinstance_t*)g_type_create_instance(my_type_id);
    
    my_instance_method(instance,78);
    my_class_method();

    printf("Is instance of class? %s\n",
            G_TYPE_CHECK_INSTANCE_TYPE(instance, my_type_id)?"yes":"no");
    printf("Is instance of class? %s\n",
            G_TYPE_CHECK_INSTANCE_TYPE(instance, G_TYPE_INT)?"yes":"no");


g_type_name querys the string representation of the name of the type.

When first creating an instance using g_type_create_instance, the class struct is automatically allocated and initialized.

In order to call a instance method, just call the function with the first argument filled as the instance pointer.

G_TYPE_CHECK_INSTANCE_TYPE checks the type of an instance.

Q: How can it know the type of the instance by merely a pointer to the instance?
A: Recall that the first field of myinstance_t (that is GTypeInstance) contains a pointer which points to its class struct (myclass_t) which begins with a GTypeClass which has a GType field which identifies its type.

This means GObject provides runtime type information (RTTI) support which C++ classes do not usually have.  Note that you need to #include<typeinfo> in C++ in order to use RTTI.

分享到:
评论

相关推荐

    Giveda_GObject_c++11_v1.5

    利用本软件,c++开发者可以在不依赖c++编译器之外的任何工具的前提下,实现c++中类与类之间的解耦合(class A对象与class B对象之间的解耦合)。 本软件支持c++11并向后兼容(支持c++11及其后续版本)。 开发环境为...

    gobject-snippets:UltiSnips C 片段有助于编写 GObject 代码

    UltiSnips C 片段有助于编写 GObject 代码 安装 这些片段使用 UltiSnips ( ) 所以你应该先安装和配置它。 我使用 Vundle ( ) 来管理 vim 插件,但这不是强制性的。 如果你使用 Vundle,你可以添加到你的 ~/.vimrc ...

    gobject_create_class_demo.tar.gz

    本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -&gt; shape -&gt;gobject 其中,square重载了shape类的info接口。

    crystal-gobject:Crystal的gobject-introspection

    crystal-gobject:Crystal的gobject-introspection

    Gobject Reference Manual

    8. 继承:GObject支持类的继承,通过g_type_class_ref()和g_type_class_peek()等函数可以访问父类的方法和属性。 9. 错误处理:GObject提供了一套错误系统,允许对象在遇到错误时发出错误信息,通过GError结构体和g...

    Gobject 离线API手册

    GObject是GTK+库的核心组件,它为C语言提供了一种面向对象的编程模型。在GTK+和Gnome开发中,GObject系统是构建复杂、可扩展软件的基础。这个离线API手册包含了GObject框架的详细信息,对于理解并利用GObject进行...

    GObject Reference Manual

    The GObject base class Object instanciation Object memory management Reference count Weak References Reference counts and cycles Object properties Accessing multiple properties at once The ...

    groonga-gobject:Groonga的GObject包装器

    Groonga GObject 描述 Groonga的GObject包装器。 去做... 安装 Debian GNU / Linux 。 运行以下命令: % sudo apt-get install -V -y gir1.2-groonga libgroonga-gobject0 的Ubuntu 。 运行以下命令: % ...

    Gobject 资料,全面介绍

    Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍Gobject 资料,全面介绍

    gobject_setup_property_demo.zip

    3. **设置类属性**:通过`g_object_class_install_property`函数,你可以向类添加自定义属性。这些属性可以有默认值,也可以通过`g_object_set`和`g_object_get`函数进行设置和获取。 4. **实现接口**:GObject系统...

    gobject:适用于PHP的静态Gobject绑定

    gtkforphp gobject扩展为GObject功能提供了语言绑定。 有关该库的文档和信息可以在找到 现在,这只不过是一个占位符。 您可以发送评论,补丁,问题 这仍然是实验性的扩展。 安装/配置 此扩展需要gtkforphp / glib...

    yard-gobject-introspection:YARD插件,用于从GObject Introspection数据检索文档

    码-对象反省码插件,用于基于GObject-Intropection构建库文档。要求Ruby / GObject-Introspection尝试一下 git clone ...

    cairo-gobject-1.15.12-3.el7.x86_64.rpm

    离线安装包,亲测可用

    python3-pygobject3:GObject库的Python 3绑定

    **Python3-pygobject3: GObject库的Python 3绑定** `python3-pygobject3` 是一个Python 3版本的绑定库,它允许Python程序员能够利用GObject库的功能,这是GNOME桌面环境的核心组件之一。GObject库是C语言编写的一个...

    lgi:使用GObject-Introspection将动态Lua绑定到GObject库

    液化天然气LGI是基于gobject内省的动态Lua绑定到基于GObject的库。 它允许直接从Lua使用基于GObject的库。 已获得许可的许可,请参见LICENSE文件全文。 该项目的主页位于。 LGI经过测试,并与标准Lua 5.1,Lua 5.2,...

    gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定.zip

    gir_ffi, 在运行时使用 FFI,为基于GObject的库自动生成绑定 GirFFI由 Matijs van Zuijlen描述使用GObject内省存储库的GNOME的ruby 绑定。状态 特性为基于任何gobject的库创建绑定。在运行时生成绑定。为选定方法...

    gobject对象系统

    GObjectClass parent_class; void (*boy_born)(void); }; GType boy_get_type(void); Boy *boy_new(void); guint boy_get_age(Boy *boy); void boy_set_age(Boy *boy, guint age); gchar *boy_get_name(Boy *boy...

    python-gobject-3.22.0-1.el7_4.1.x86_64.rpm

    离线安装包,亲测可用

    GObject对象系统

    GObjectClass parent_class; // 父类指针,指向GObjectClass void (*boy_born)(void); // 出生的方法指针 }; GType boy_get_type(void); Boy *boy_new(void); guint boy_get_age(Boy *boy); void boy_set_age...

    avahi-gobject-0.6.25-11.el6.i686.rpm

    avahi-gobject-0.6.25-11.el6.i686.rpm是centos工具包。

Global site tag (gtag.js) - Google Analytics