- 浏览: 129476 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
cloverprince:
z707208280 写道写多表查询咋整? select 列 ...
[自己动手]用Java的反射实现DAO -
z707208280:
写多表查询咋整? select 列 这里用别名.字段 这咋整手 ...
[自己动手]用Java的反射实现DAO -
亮亮婷婷:
4楼正解,顶!
能在Eclipse 3.7中给m2e提供WTP支持的插件在哪里? -
cloverprince:
沙舟狼客 写道貌似2b青年的代码很有技术含量嗯,简单问题复杂化 ...
普通青年 文艺青年 2B青年 -
沙舟狼客:
貌似2b青年的代码很有技术含量
普通青年 文艺青年 2B青年
A good practice of Object-oriented Programming is to hide implementation details from the user. As explained before, programmers are encouraged to use "private" fields. However, if you want to let users access those fields, you could do this:
These two functions are called "getter" and "setter". Instead of directly modifying the data, getters and setters may do extra works like data validating, changing other members, computing the output or notifying other objects about this change. Java programmers also use getters and setters pervasively.
Now let's introduce the concept of "property". A class may have many "properties". Properties can be got and set. When got or set, it appears as if getters or setters are called.
.NET Languages have language-level properties. The above program can be written in equivalent C# code as:
Although Java does not have language-level "property" feature, it uses JavaBean convensions and reflection to simulate properties.
In GObject library, the GObject class allows user to add properties to their classes.
Full code here. Don't read it now.
Let's concentrate on the class initializing function.
A property is registered with g_object_class_install_property function. It takes three parameters: the class struct, the property-id and a GParamSpec struct. The GParamSpec struct my_param_spec contains informations about the property including its name, long name, discription, default value as well as access flags.
Each property need a unique integer identifies.
A getter and a setter function is required for this class. They are virtual methods of GObject class.
And they overrides the default get_property and set_property in the GObject class. These are done in my_class_init_func:
Whenever a property is got, the get_property virtual function is called. Then the property_id is passed in which is supposed to be identified. A switch structure is used to delegate this property to their respective getter codes where the GValue *value parameter is supposed to be filled. It is similar for the setter.
In the main() function, instances are created using g_object_new() function.
The first parameter is the type-id. Then there are pairs of property-names and values. The variable-length parameter list ends with a NULL. The properties specified here will be initialized on creating.
From then on, you can get or set the properties using g_object_get_property and g_object_set_property. You have to use GValue container to do so. A GValue conatainer may contain a value of any type and it always know what type it is containing. It is equivalent to QVariant if you have used Qt library for C++.
You have to initialize the memory block of the GValue instance with '\0's. You need to use g_value_init to specify what type it contains and use g_value_unset when you no longer use it.
In the GParamSpec struct passed into g_object_class_install_property, flags can be used to specify whether it is readable or writable. There are G_PARAM_READABLE and G_PARAM_WRITABLE flags. G_PARAM_CONSTRUCT means that if you do not initialize the property when the instance is created, it will be initialized to the default value. It is not required to have G_PARAM_CONSTRUCT in order to initialize it in g_object_new. You can do this as long as it is writable. And G_PARAM_CONSTRUCT_ONLY constraint that this property can only be set when the object is constructed.
typedef { int foo; } MyInstancePrivate; int get_foo(MyInstance* instance) { MyInstancePrivate * priv = G_TYPE_INSTANCE_GET_PRIVATE(instance, MY_TYPE, MyInstancePrivate); return priv->foo; } void set_foo(MyInstance* instance, int new_foo) { MyInstancePrivate * priv = G_TYPE_INSTANCE_GET_PRIVATE(instance, MY_TYPE, MyInstancePrivate); priv->foo = new_foo; }
These two functions are called "getter" and "setter". Instead of directly modifying the data, getters and setters may do extra works like data validating, changing other members, computing the output or notifying other objects about this change. Java programmers also use getters and setters pervasively.
Now let's introduce the concept of "property". A class may have many "properties". Properties can be got and set. When got or set, it appears as if getters or setters are called.
.NET Languages have language-level properties. The above program can be written in equivalent C# code as:
class Hello { private int _foo; public int foo { get { return _foo; } set { _foo = value; } } }
Although Java does not have language-level "property" feature, it uses JavaBean convensions and reflection to simulate properties.
In GObject library, the GObject class allows user to add properties to their classes.
Full code here. Don't read it now.
/* A subclass of GObject with a property. */ #include <stdio.h> #include <glib-object.h> #define PROPERTY_ID_OF_NAME 1 #define PROPERTY_ID_OF_NUMBER 2 typedef struct { GObject something_as_boilerplate; char *private_name; int private_number; } myinstance_t; typedef struct { GObjectClass something_as_boilerplate; } myclass_t; GType get_my_typeid(); void my_getter(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { myinstance_t *instance = G_TYPE_CHECK_INSTANCE_CAST( object,get_my_typeid(), myinstance_t); switch(property_id) { case PROPERTY_ID_OF_NAME: g_value_set_string(value,instance->private_name); break; case PROPERTY_ID_OF_NUMBER: g_value_set_int(value,instance->private_number); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec); break; } } void my_setter(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { myinstance_t *instance = G_TYPE_CHECK_INSTANCE_CAST( object,get_my_typeid(), myinstance_t); switch(property_id) { case PROPERTY_ID_OF_NAME: g_free(instance->private_name); instance->private_name = g_value_dup_string(value); break; case PROPERTY_ID_OF_NUMBER: instance->private_number = g_value_get_int(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec); break; } } void my_instance_init_func(myinstance_t *instance, gpointer data) { } void my_class_init_func(myclass_t* klass, gpointer data) { G_OBJECT_CLASS(klass)->get_property = my_getter; G_OBJECT_CLASS(klass)->set_property = my_setter; GParamSpec *my_param_spec; // Property "name" my_param_spec = g_param_spec_string( "name", "Name property", "The name property of my class. Can be used on constructing.", "All your property are belong to us.", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT ); g_object_class_install_property( G_OBJECT_CLASS(klass), PROPERTY_ID_OF_NAME, my_param_spec ); // Property "number" my_param_spec = g_param_spec_int( "number", "Number property", "The number property of my class.", G_MININT, G_MAXINT, 42, G_PARAM_READABLE | G_PARAM_WRITABLE ); g_object_class_install_property( G_OBJECT_CLASS(klass), PROPERTY_ID_OF_NUMBER, my_param_spec ); } GType get_my_typeid() { static my_type_id = 0; if(my_type_id==0) { GTypeInfo my_type_info = { sizeof(myclass_t), //class_size; NULL, //base_init; NULL, //base_finalize; /* classed types, instantiated types */ (GClassInitFunc)my_class_init_func, //class_init; NULL, //class_finalize; NULL, //class_data; /* instantiated types */ sizeof(myinstance_t),//instance_size; 0, //n_preallocs; (GInstanceInitFunc)my_instance_init_func, //instance_init; /* value handling */ NULL, //value_table; }; my_type_id = g_type_register_static( G_TYPE_OBJECT, "MyClass", &my_type_info, 0 ); } return my_type_id; } int main() { g_type_init(); printf("Type id: %d\n",get_my_typeid()); printf("Type name: %s\n",g_type_name(get_my_typeid())); GValue *val = g_new0(GValue,1); // the first object myinstance_t *instance = (myinstance_t*)g_object_new(get_my_typeid(),NULL); g_value_init(val,G_TYPE_STRING); g_object_get_property(G_OBJECT(instance),"name",val); printf("Property \"name\": [%s]\n",g_value_get_string(val)); g_value_unset(val); g_value_init(val,G_TYPE_INT); g_object_get_property(G_OBJECT(instance),"number",val); printf("Property \"number\": [%d]\n",g_value_get_int(val)); g_value_unset(val); g_object_unref(instance); // the second object instance = (myinstance_t*)g_object_new(get_my_typeid(), "name","blahblah", "number",75, NULL); g_value_init(val,G_TYPE_STRING); g_object_get_property(G_OBJECT(instance),"name",val); printf("Property \"name\": [%s]\n",g_value_get_string(val)); g_value_unset(val); g_value_init(val,G_TYPE_INT); g_object_get_property(G_OBJECT(instance),"number",val); printf("Property \"number\": [%d]\n",g_value_get_int(val)); g_value_unset(val); g_value_init(val,G_TYPE_INT); g_value_set_int(val,81); g_object_set_property(G_OBJECT(instance),"number",val); g_value_unset(val); g_value_init(val,G_TYPE_INT); g_object_get_property(G_OBJECT(instance),"number",val); printf("Property \"number\": [%d]\n",g_value_get_int(val)); g_value_unset(val); g_object_unref(instance); g_free(val); return 0; }
Let's concentrate on the class initializing function.
void my_class_init_func(myclass_t* klass, gpointer data) { G_OBJECT_CLASS(klass)->get_property = my_getter; G_OBJECT_CLASS(klass)->set_property = my_setter; GParamSpec *my_param_spec; // Property "name" my_param_spec = g_param_spec_string( "name", "Name property", "The name property of my class. Can be used on constructing.", "All your property are belong to us.", G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT ); g_object_class_install_property( G_OBJECT_CLASS(klass), PROPERTY_ID_OF_NAME, my_param_spec ); // Property "number" my_param_spec = g_param_spec_int( "number", "Number property", "The number property of my class.", G_MININT, G_MAXINT, 42, G_PARAM_READABLE | G_PARAM_WRITABLE ); g_object_class_install_property( G_OBJECT_CLASS(klass), PROPERTY_ID_OF_NUMBER, my_param_spec ); }
A property is registered with g_object_class_install_property function. It takes three parameters: the class struct, the property-id and a GParamSpec struct. The GParamSpec struct my_param_spec contains informations about the property including its name, long name, discription, default value as well as access flags.
Each property need a unique integer identifies.
#define PROPERTY_ID_OF_NAME 1 #define PROPERTY_ID_OF_NUMBER 2
A getter and a setter function is required for this class. They are virtual methods of GObject class.
void my_getter(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { myinstance_t *instance = G_TYPE_CHECK_INSTANCE_CAST( object,get_my_typeid(), myinstance_t); switch(property_id) { case PROPERTY_ID_OF_NAME: g_value_set_string(value,instance->private_name); break; case PROPERTY_ID_OF_NUMBER: g_value_set_int(value,instance->private_number); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec); break; } } void my_setter(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { myinstance_t *instance = G_TYPE_CHECK_INSTANCE_CAST( object,get_my_typeid(), myinstance_t); switch(property_id) { case PROPERTY_ID_OF_NAME: g_free(instance->private_name); instance->private_name = g_value_dup_string(value); break; case PROPERTY_ID_OF_NUMBER: instance->private_number = g_value_get_int(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec); break; } }
And they overrides the default get_property and set_property in the GObject class. These are done in my_class_init_func:
G_OBJECT_CLASS(klass)->get_property = my_getter; G_OBJECT_CLASS(klass)->set_property = my_setter;
Whenever a property is got, the get_property virtual function is called. Then the property_id is passed in which is supposed to be identified. A switch structure is used to delegate this property to their respective getter codes where the GValue *value parameter is supposed to be filled. It is similar for the setter.
In the main() function, instances are created using g_object_new() function.
instance = (myinstance_t*)g_object_new(get_my_typeid(), "name","blahblah", "number",75, NULL);
The first parameter is the type-id. Then there are pairs of property-names and values. The variable-length parameter list ends with a NULL. The properties specified here will be initialized on creating.
From then on, you can get or set the properties using g_object_get_property and g_object_set_property. You have to use GValue container to do so. A GValue conatainer may contain a value of any type and it always know what type it is containing. It is equivalent to QVariant if you have used Qt library for C++.
GValue *val = g_new0(GValue,1); g_value_init(val,G_TYPE_INT); g_value_set_int(val,81); g_object_set_property(G_OBJECT(instance),"number",val); g_value_unset(val);
You have to initialize the memory block of the GValue instance with '\0's. You need to use g_value_init to specify what type it contains and use g_value_unset when you no longer use it.
In the GParamSpec struct passed into g_object_class_install_property, flags can be used to specify whether it is readable or writable. There are G_PARAM_READABLE and G_PARAM_WRITABLE flags. G_PARAM_CONSTRUCT means that if you do not initialize the property when the instance is created, it will be initialized to the default value. It is not required to have G_PARAM_CONSTRUCT in order to initialize it in g_object_new. You can do this as long as it is writable. And G_PARAM_CONSTRUCT_ONLY constraint that this property can only be set when the object is constructed.
发表评论
-
GObject 2-01: A convention-compliant minimal complete working example.
2009-12-18 01:19 2130My coding style has been so wei ... -
GObject 09: An Interface
2009-11-09 16:56 1904An interface is a class with mu ... -
GObject 08: A class with a signal
2009-10-22 17:09 2607A GObject may emit signals to s ... -
GObject 06: A subclass of GObject
2009-10-21 13:44 1723This time GObject refers to the ... -
GObject 05: An Inheritable class.
2009-10-21 01:32 1986In this article I will implemen ... -
GObject 04: A class with private members
2009-10-21 00:49 1903A private member is a member th ... -
GObject 03: An Instantiatable Class
2009-10-16 16:35 1813Most of the time classes are in ... -
GObject 02: A classed type
2009-10-13 16:53 1793Now I am going to create a clas ... -
GObject 01: My first fundamental type.
2009-10-13 01:25 1861GObject system handles "ty ... -
GObject 00: A bottom-up introduction to the GObject system
2009-10-13 00:34 2163This document introduces the GO ...
相关推荐
离线安装包,亲测可用
离线安装包,亲测可用
本示例用于演示GObject创建新类,类的继承与重载。代码实现了shape和square类,继承关系为: square -> shape ->gobject 其中,square重载了shape类的info接口。
- NEW: Support for setting GObject.data in editor. - NEW: Support for setting selectedIcon of list item in editor. - IMPROVED: Add UIConfig.depthSupportForPaitingMode. - IMPROVED: Set sorting order of...
离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
在IT领域,特别是软件开发中,GObject是一个关键的概念,它是GTK+库中的基础对象模型。GObject系统为C语言提供了面向对象编程的支持,而这个"gobject_setup_property_demo.zip"压缩包显然提供了一个关于如何使用...
离线安装包,亲测可用
离线安装包,亲测可用
官方离线安装包,亲测可用
离线安装包,亲测可用
官方离线安装包,亲测可用
官方离线安装包,亲测可用
离线安装包,亲测可用
官方离线安装包,亲测可用
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
官方离线安装包,亲测可用
官方离线安装包,亲测可用
官方离线安装包,亲测可用