GObject:自定义类创建实例(继承、重载)

概述

本文旨在介绍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( )的实现。

如下代码含义:

  • 参数1 “Shape”:注册新的类名称(与结构体同名)
  • 参数2 “shape”:注册新类初始化函数前缀,比如shape_init(Shape *shape)。这里填写什么字符串(假设为:XXX),就要实现XXX_init,XXX_class_init,XXX_get_type。
  • 参数3 “G_TYPE_OBJECT”:父类的类型,这里表示Shape的父类是OBJECT。其实就是对应父类的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 <glib-object.h>

/* 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 <glib.h>

#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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值