GObject对象系统 (2)

 

对象的实现

下面的代码实现了上面的Boy对象的定义:

 

 

 

/* boy.c */
#include "boy.h"
enum { BOY_BORN, LAST_SIGNAL };
static gint boy_signals[LAST_SIGNAL] = { 0 };
static void boy_cry (void);
static void boy_born(void);
static void boy_init(Boy *boy);
static void boy_class_init(BoyClass *boyclass);
GType boy_get_type(void)
{
	static GType boy_type = 0;
	if(!boy_type)
	{
		static const GTypeInfo boy_info = {
			sizeof(BoyClass),
			NULL,NULL,
			(GClassInitFunc)boy_class_init,
			NULL,NULL,
			sizeof(Boy),
			0,
			(GInstanceInitFunc)boy_init
		};
		boy_type = g_type_register_static(G_TYPE_OBJECT,"Boy",&boy_info,0);
	}
	return boy_type;
}
static void boy_init(Boy *boy)
{
	boy->age = 0;
	boy->name = "none";
	boy->cry = boy_cry;
}
static void boy_class_init(BoyClass *boyclass)
{
	boyclass->boy_born = boy_born;
	boy_signals[BOY_BORN] = g_signal_new("boy_born",
				BOY_TYPE,
				G_SIGNAL_RUN_FIRST,
				G_STRUCT_OFFSET(BoyClass,boy_born),
				NULL,NULL,
				g_cclosure_marshal_VOID__VOID,
				G_TYPE_NONE, 0, NULL);
}
Boy *boy_new(void)
{
	Boy *boy;
	boy = g_object_new(BOY_TYPE, NULL);
	g_signal_emit(boy,boy_signals[BOY_BORN],0);
	return boy;
}
int boy_get_age(Boy *boy)
{
	return boy->age;
}
void boy_set_age(Boy *boy, int age)
{
	boy->age = age;
}
char *boy_get_name(Boy *boy)
{
	return boy->name;
}
void boy_set_name(Boy *boy, char *name)
{
	boy->name = name;
}
Boy*  boy_new_with_name(gchar *name)
{
	Boy* boy;
	boy = boy_new();
	boy_set_name(boy, name);
	return boy;
}
Boy*  boy_new_with_age(gint age)
{
	Boy* boy;
	boy = boy_new();
	boy_set_age(boy, age);
	return boy;
}
Boy *boy_new_with_name_and_age(gchar *name, gint age)
{
	Boy *boy;
	boy = boy_new();
	boy_set_name(boy,name);
	boy_set_age(boy,age);
	return boy;
}
static void boy_cry (void)
{
	g_print("The Boy is crying ....../n");
}
static void boy_born(void)
{
	g_print("Message : A boy was born ./n");
}
void  boy_info(Boy *boy)
{
	g_print("The Boy name is %s/n", boy->name);
	g_print("The Boy age is %d/n", boy->age);
}

在这段代码中,出现了实现Boy对象的关键函数,这是在Boy对象的定义中未出现的,也是没必要出现的。

就是两个初始化函数,boy_init和boy_class_init,它们分别用来初始化实例结构和类结构。

它们并不被在代码中明显调用,关键是将其用宏转换为地址指针,然后赋值到GTypeInfo结构中,然后由GType系统自行处理,

同时将它们定义为静态的也是非常必要的。

 

GTypeInfo结构中定义了对象的类型信息,包括以下内容:

  1. 包括类结构的长度(必需,即我们定义的BoyClass结构的长度);
  2. 基础初始化函数(base initialization function,可选);
  3. 基础结束化函数(base finalization function,可选); 

    (以上两个函数可以对对象使用的内存来做分配和释放操作,使用时要用GBaseInitFunc和GBaseFinalizeFunc来转换为指针,

    本例中均未用到,故设为NULL。)

  4. 类初始化函数(即我们这里的boy_class_init函数,用GclassInit宏来转换,可选,仅用于类和实例类型);
  5. 类结束函数(可选);
  6. 实例初始化函数(可选,即我们这里的boy_init函数);
  7. 最后一个成员是GType变量表(可选)。

定义好GTypeInfo结构后就可以用g_type_register_static函数来注册对象的类型了。

g_type_register_static函数用来注册对象的类型,它的第一个参数是表示此对象的父类的对象类型,我们这里是G_TYPE_OBJECT,

这个宏用来表示GObject的父类;第二个参数表示此对象的名称,这里为"Boy";第三个参数是此对象的GTypeInfo结构型指针,

这里赋值为&boyinfo;第四个参数是对象注册成功后返回此对象的整型ID标识。

 

g_object_new函数,用来创建一个基于G_OBJECT的对象,它可以有多个参数,第一个参数是上面说到的已注册的对象标识ID;

第二个参数表示后面参数的数量,如果为0,则没有第三个参数;第三个参数开始类型都是GParameter类型,它也是一个结构型,

定义为:

struct GParameter{

		const gchar* name;
		GValue value;
};
关于GValue,它是变量类型的统一定义,它是基础的变量容器结构,用于封装变量的值和变量的类型,可以GOBJECT文档的GVALUE部分。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值