Gobject的对象方法有如下几种:
1、非虚拟公共方法
2、虚拟公共方法
3、虚拟私有方法
1、非虚拟公共方法
这个是最简单的,提供了一种作用于对象的简单方法。 在头文件中提供函数原型,并在源文件中提供该原型的实现。
/* declaration in the header. */ void viewer_file_open (ViewerFile *self, GError **error); /* implementation in the source file */ void viewer_file_open (ViewerFile *self, GError **error) { g_return_if_fail (VIEWER_IS_FILE (self)); g_return_if_fail (error == NULL || *error == NULL); /* do stuff here. */ }
2、虚拟公共方法
这是创建GObject的可覆盖函数的首选:
(1)在公共头文件中的类结构中定义通用方法及其虚函数
(2)在头文件中定义通用方法,并在源文件中实现它
(3)在源文件中实现虚拟函数的基本版本,并在对象的class_init函数中初始化该实现的虚函数指针; 或者将其赋值为NULL的纯虚拟函数,该函数必须由派生类覆盖。
(4)在需要覆盖它的每个派生类中重新实现虚拟函数
请注意,虚拟函数只能在类可派生时定义,使用G_DECLARE_DERIVABLE_TYPE声明,因此可以定义类结构。
/* declaration in viewer-file.h. */ #define VIEWER_TYPE_FILE viewer_file_get_type () G_DECLARE_DERIVABLE_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject) struct _ViewerFileClass { GObjectClass parent_class; /* stuff */ void (*open) (ViewerFile *self, GError **error); /* Padding to allow adding up to 12 new virtual functions without * breaking ABI. */ gpointer padding[12]; }; void viewer_file_open (ViewerFile *self, GError **error); /* implementation in viewer-file.c */ void viewer_file_open (ViewerFile *self, GError **error) { ViewerFileClass *klass; g_return_if_fail (VIEWER_IS_FILE (self)); g_return_if_fail (error == NULL || *error == NULL); klass = VIEWER_FILE_GET_CLASS (self); g_return_if_fail (klass->open != NULL); klass->open (self, error); }
上面的代码简单地将打开的调用重定向到相关的虚拟函数。
可以在对象的class_init函数中为此类方法提供默认实现:将klass->open字段初始化为指向实际实现的指针。 默认情况下,不被继承的类方法被初始化为NULL,因此被认为是“纯虚拟”。
static void viewer_file_real_close (ViewerFile *self, GError **error) { /* Default implementation for the virtual method. */ } static void viewer_file_class_init (ViewerFileClass *klass) { /* this is not necessary, except for demonstration purposes. * * pure virtual method: mandates implementation in children. */ klass->open = NULL; /* merely virtual method. */ klass->close = viewer_file_real_close; } void viewer_file_open (ViewerFile *self, GError **error) { ViewerFileClass *klass; g_return_if_fail (VIEWER_IS_FILE (self)); g_return_if_fail (error == NULL || *error == NULL); klass = VIEWER_FILE_GET_CLASS (self); /* if the method is purely virtual, then it is a good idea to * check that it has been overridden before calling it, and, * depending on the intent of the class, either ignore it silently * or warn the user. */ g_return_if_fail (klass->open != NULL); klass->open (self, error); } void viewer_file_close (ViewerFile *self, GError **error) { ViewerFileClass *klass; g_return_if_fail (VIEWER_IS_FILE (self)); g_return_if_fail (error == NULL || *error == NULL); klass = VIEWER_FILE_GET_CLASS (self); if (klass->close != NULL) klass->close (self, error); }
(3)虚拟私有方法
这些与虚拟公共方法非常相似。他们只是没有直接调用公共函数。头文件仅包含虚函数的声明:
/* declaration in viewer-file.h. */ struct _ViewerFileClass { GObjectClass parent; /* Public virtual method as before. */ void (*open) (ViewerFile *self, GError **error); /* Private helper function to work out whether the file can be loaded via * memory mapped I/O, or whether it has to be read as a stream. */ gboolean (*can_memory_map) (ViewerFile *self); /* Padding to allow adding up to 12 new virtual functions without * breaking ABI. */ gpointer padding[12]; }; void viewer_file_open (ViewerFile *self, GError **error);
这些虚拟函数通常用于将部分功能委托给子类实现:
/* this accessor function is static: it is not exported outside of this file. */ static gboolean viewer_file_can_memory_map (ViewerFile *self) { return VIEWER_FILE_GET_CLASS (self)->can_memory_map (self); } void viewer_file_open (ViewerFile *self, GError **error) { g_return_if_fail (VIEWER_IS_FILE (self)); g_return_if_fail (error == NULL || *error == NULL); /* * Try to load the file using memory mapped I/O, if the implementation of the * class determines that is possible using its private virtual method. */ if (viewer_file_can_memory_map (self)) { /* Load the file using memory mapped I/O. */ } else { /* Fall back to trying to load the file using streaming I/O… */ } }
同样,可能会为这个虚拟私有函数提供一个默认的实现。
static gboolean viewer_file_real_can_memory_map (ViewerFile *self) { /* As an example, always return false. Or, potentially return true if the * file is local. */ return FALSE; } static void viewer_file_class_init (ViewerFileClass *klass) { /* non-pure virtual method; does not have to be implemented in children. */ klass->can_memory_map = viewer_file_real_can_memory_map; }
派生类可以用如下代码覆盖该方法:
static void viewer_audio_file_class_init (ViewerAudioFileClass *klass) { ViewerFileClass *file_class = VIEWER_FILE_CLASS (klass); /* implement pure virtual function. */ file_class->can_memory_map = viewer_audio_file_can_memory_map; }
时间: 2024-11-01 22:57:04