十五、GObject对象私有结构体
创建一个对象的时候,一个对象包含两部分,类结构体和实例结构体。所以私有结构体也分两种:
-
类里面添加私有结构体
-
实例里面添加私有结构体
1 类添加私有结构体
/* 1. 结构体定义 */
typedef struct _MyObjectClassPrivate MyObjectClassPrivate;
struct _MyObjectClassPrivate
{
gint secret_class_count;
};
/* 2. 类型定义 */
/**
* g_define_type_id是G_DEFINE_TYPE_WITH_CODE宏里面,表示MyObject类型的ID。
*/
G_DEFINE_TYPE_WITH_CODE (MyObject, my_object, G_TYPE_OBJECT,
g_type_add_class_private (g_define_type_id, sizeof (MyObjectClassPrivate)) );
2 实例添加私有结构体
2.1 结构体名称(类型名+Private)
只需要在实例对象名称TypeName后面加(Private)
/* 一定要是 TestObjectPrivate,因为 G_DECLARE_FINAL_TYPE 和 G_DECLARE_DERIVABLE_TYPE 没有 typedef struct _TestObjectPrivate TestObjectPrivate */
typedef struct _TestObjectPrivate TestObjectPrivate;
struct _TestObjectPrivate{
int dummy_0;
float dummy_1;
} TestObjectPrivate;
2.2 如何定义
方式一:
G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT,
G_ADD_PRIVATE (TestObject))
方式二:
G_DEFINE_TYPE_WITH_PRIVATE (TestObject, test_object, G_TYPE_OBJECT)
其实核心都是一样,都是调用 g_type_add_instance_private
,然后把私有结构体的大小赋值给 private_size
。
对象被创建的时候,其实创建的大小等于 instance_size + private_size
2.3 问题总结
私有结构体能否被继承:
可以被继承,一般不能被访问到(除非定义到同一个源文件里面)。私有结构体一般被定义到源文件里面,还有获取私有结构体的 类型_名称_get_instance_private()
函数也是在源文件里面定义的。
为什么有时候实例结构体定义的时候有私有结构体指针:
为了便于外部找到私有结构体地址,我们以 GApplication
为例:
/* gapplication.h */
struct _GApplication
{
/*< private >*/
GObject parent_instance;
GApplicationPrivate *priv;
};
/* gapplication.c */
static void
g_application_init (GApplication *application)
{
/* 会把实际的私有结构体地址获取到,赋值给 application->priv */
application->priv = g_application_get_instance_private (application);
...
}