转载请注明出处 blog.csdn.net/pingf0 或www.cnblogs.com/pingf
Part 6
接上文。
和官方的tutorial一样,在此部分,简要叙述下GObject中的方法。
其分为三类,
非虚公共方法
虚公共方法
虚私有方法
公共方法比较简单,所以也就没啥好说的了,看代码,其实就是明白着从外部调用
/* declaration in the header. */
void jc_boy_do_action (JcBoy *self, /* parameters */);
/* implementation in the source file */
void
jc_boy_do_action (JcBoy *self, /* parameters */)
{
g_return_if_fail (JC_IS_BOY (self));
/* do stuff here. */
}
虚公共方法则稍微绕了一圈
Code
struct _JcBoyClass
{
GObjectClass parent_class;
/* stuff */
void (*do_action) (JcBoy *self, /* parameters */);
};
void jc_boy_do_action (JcBoy *self, /* parameters */);
void
jc_boy_do_action (JcBoy *self, /* parameters */)
{
g_return_if_fail (JC_IS_BOY (self));
JC_BOY_GET_CLASS (self)->do_action (self, /* parameters */);
}
可以看到是在类结构中用了个函式指针,当然这个指针肯定是要在类结构初始化时赋值的。当然最后还是留了个外部公共函式。
再具体看下
Code
static void
jc_boy_real_do_action_two (JcBoy *self, /* parameters */)
{
/* Default implementation for the virtual method. */
}
static void
jc_boy_class_init (JcBoy *klass)
{
/* pure virtual method: mandates implementation in children. */
klass->do_action_one = NULL;
/* merely virtual method. */
klass->do_action_two = jc_boy_real_do_action_two;
}
void
jc_boy_do_action_one (JcBoy *self, /* parameters */)
{
g_return_if_fail (JC_IS_BOY (self));
JC_BOY_GET_CLASS (self)->do_action_one (self, /* parameters */);
}
void
jc_boy_do_action_two (JcBoy *self, /* parameters */)
{
g_return_if_fail (JC_IS_BOY (self));
JC_BOY_GET_CLASS (self)->do_action_two (self, /* parameters */);
}
注意看类结构klass->do_action_one = NULL,这就算是GObject中的纯虚函式了,呵呵,关键在我们的理解,毕竟C本身不是面向对象的,这还是模拟。
看到这里我们不禁会思考,既然虚公共方法都这样声明了,那么须私有方法又是什么样的呢?
答案比较恶搞,其实GObject中所谓的虚私有方法声明起来和虚公有方法是一样一样滴。唯一的不同就是不提供外部调用的函式【就是上面程序中的jc_boy_do_action_one和jc_boy_do_action_two】!这就决定了只能是类结构内部使用了,除了内部调用外,GObject的虚私有方法更多是用来使用在类的继承中,子类实现父类的纯虚方法。
下面举个例子,假设有个类JcMan继承自JcBoy,实现了JcBoy中的纯虚函式do_action_one
Code
static void
jc_man_real_do_action_one (JcBoy *self, /* parameters */)
{
/* Default implementation for the virtual method. */
}
static void
jc_man_class_init (JcManClass *klass)
{
JcBoyClass *boy_class = JC_BOY_CLASS (klass);
/* implement pure virtual class function. */
boy_class-> do_action_one = jc_man_real_do_action_one;
}
void
jc_man_do_action_one (JcMan *self, /* parameters */)
{
g_return_if_fail (JC_IS_MAN (self));
JcBoy *boy = JC_BOY (self);
JC_BOY_GET_CLASS (self)->do_action_one (boy /* parameters */);
}