本文旨在介绍GObject如何自定义新类,GObject的一些基础概念(类、对象、实例)可参考【GObject 对象-类-实例概念介绍】。
GObject提供了丰富的宏定义,使用G_DEFINE_TYPE 宏定义可以帮助我们快速的定义一个新的类。当然如果不想借助这个宏定义,则可以自己实现XXX_get_type()函数,并在此函数内调用g_type_register_static() 注册新的类。我们在使用g_object_new函数创建刚才注册的类时,第一个参数就是XXX_get_type( )。而XXX_get_type( )就是实现向GObject注册新的类(与自己调用g_type_register_static接口进行注册是一样的)的入口。而G_DEFINE_TYPE的本质只是帮我们定义好了XXX_get_type( )的实现。
如下代码含义:
shape_init(Shape *shape)
。这里填写什么字符串(假设为:XXX),就要实现XXX_init,XXX_class_init,XXX_get_type。G_DEFINE_TYPE(Shape, shape, G_TYPE_OBJECT);
定义一个新的类,最少要实现三个函数:
/* 类结构 */
typedef struct _mytest {
int member1;
char member2;
void (*func)(void);
/* 略 */
} Mytest;
//对象初始化函数
void mytest_init(Mytest *arg);
//类的初始化函数
void mytest_class_init(MytestClass *class);
//该函数实现向GObject注册我们新定义的mytest类,可通过G_DEFINE_TYPE进行实现。
Gtype mytest_get_type(void)
接下来我们展示一个Demo,该Demo实现了一个shape类和一个square类,square类继承了shape类,并且重载了shape类的info()函数。
shape.h代码:
#ifndef _SHAPE_H_
#define _SHAPE_H_
#include
/* define new class type. */
#define SHAPE_TYPE (shape_get_type())
/* Gobject* to Shape* */
#define SHAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SHAPE_TYPE, Shape))
typedef struct _Shape Shape;
typedef struct _ShapeClass ShapeClass;
struct _Shape {
GObject parent;
gint type;
gchar *name;
void (*info)(void);
};
struct _ShapeClass {
GObjectClass parent_class;
};
/* xxx_init() xxx_class_init() xxx_get_type() must exist */
GType shape_get_type(void);
gchar *shape_get_name(Shape *shape);
#endif // _SHAPE_H_
shape.c代码:
#include "shape.h"
/* very importent!!! */
G_DEFINE_TYPE(Shape, shape, G_TYPE_OBJECT);
static void shape_info(void) {
g_print("+++++ This is a shape type +++++\n");
}
static void shape_init(Shape *shape)
{
g_print("+++++ %s is called! +++++\n", __func__);
shape->name = "shape";
shape->type = 0;
shape->info = shape_info;
}
static void shape_class_init(ShapeClass *class)
{
g_print("+++++ %s is called! +++++\n", __func__);
}
char *shape_get_name(Shape *shape)
{
g_print("+++++ shape name: %s +++++\n", shape->name);
}
square.h代码:
#ifndef _SUEQRE_H_
#define _SUEQRE_H_
#include "shape.h"
/* define new class type. */
#define SQUARE_TYPE (square_get_type())
/* Gobject* to Square* */
#define SQUARE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SQUARE_TYPE, Square))
typedef struct _Square Square;
typedef struct _SquareClass SquareClass;
struct _Square {
Shape parent;
gint width;
gint height;
};
struct _SquareClass {
ShapeClass parent_class;
};
/* xxx_init() xxx_class_init() xxx_get_type() must exist */
GType square_get_type(void);
gint square_set_wh(Square *square, gint w, gint h);
gint square_get_area(Square *square);
#endif // _SUEQRE_H_
square.c代码:
#include "square.h"
/* very importent!!! */
G_DEFINE_TYPE(Square, square, SHAPE_TYPE);
static void shape_info(void) {
g_print("+++++ This is a square type +++++\n");
}
static void square_init(Square *square)
{
Shape *shape = SHAPE(square);
g_print("+++++ %s is called! +++++\n", __func__);
shape->name = "shape";
shape->type = 0;
shape->info = shape_info;
square->width = 0;
square->height = 0;
}
static void square_class_init(SquareClass *class)
{
g_print("+++++ %s is called! +++++\n", __func__);
}
gint square_set_wh(Square *square, gint w, gint h)
{
g_print("+++++ %s is called! +++++\n", __func__);
square->width = w;
square->height = h;
}
gint square_get_area(Square *square)
{
g_print("+++++ %s is called! +++++\n", __func__);
return square->width * square->height;
}
main.c代码:
#include
#include "shape.h"
#include "square.h"
int main(int argc, char *argv[])
{
Shape *shape = NULL;
Square *square = NULL;
g_print("Shape info:\n");
shape = g_object_new(SHAPE_TYPE, NULL);
shape->info();
g_print("\n");
g_print("Square info:\n");
square = g_object_new(SQUARE_TYPE, NULL);
SHAPE(square)->info();
square_set_wh(square, 3, 2);
g_print("area:%d\n", square_get_area(square));
return TRUE;
}
运行结果:
完整工程地址如下(包含Makefile):
https://download.csdn.net/download/lyy901135/11424214