Gobject的对象方法

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

Gobject的对象方法的相关文章

[oc第四天]【掌握】03-self用在对象方法中

[掌握]03-self用在对象方法中 self 指代的是调用当前对象方法的那个对象 过一遍代码就懂来 [掌握]04-self用在类方法中 [p class]返回的实质就是当前类(类对象) [self run] [了解] 05-self修饰变量 self->speed = speed; 如果同名,局部变量会暂时屏蔽全局变量的作用域 int a = 10; a = a; self->speed访问的是实例变量 加上self后表示访问的就是类的实例变量 不加self访问的局部变量 [掌握]08-继承

self在类方法和对象方法中的应用

谁调用当前方法,self就代表谁 * self在对象方法中,self代表当前对象 * self在类方法中个,self代表类 > self在对象方法中 可以利用self->属性名称的方式访问成员变量 > [self 方法名称]; 调用其它方法(类方法/对象方法)

Oracle自定义数据类型 2 (调用对象方法)

调用对象方法 调用对象方法基于类型创建表后,就可以在查询中调用对象方法 A. 创建基于对象的表语法: create   table   <表名>   of   <对象类型>意义:此表具有该类型和member方法的所有属性, 我们不能通过DBA   STUDIO的表数据编辑器来编辑数据. 例:create   table   FLIGHT_SCH_TAB   of   FLIGHT_SCH_TYPE insert   into   FLIGHT_SCH_TAB     values(

Object-c 类、对象方法

// //  main.m //  firestMethod2 // //  Created by AleuxQ on 16/3/14. //  Copyright © 2016年 AleuxQ. All rights reserved. // #import <Foundation/Foundation.h> /* 事物名称:iphone 属性:型号.cpu,尺寸,颜色 行为:打电话 发短信,上网 */ //1.编写类的申明 //###############################

OC基础复习(三)之类方法和对象方法的理解

面向对象的难易点:其实也就是封装:要会调封装,也要会自己封装,封装就是给出一些接口,让我们去用,我们不关心其实现,但往往学的时候不踏实 说他容易是用着容易,只要有接口,就可以完成很多我们想要的功能,但往往分不清功能是自己能实现还是通过别人写好的框架或者方法来帮我实现 所以需要记忆一些常用方法和框架.把自己的算法思想和一些接口框架相结合. OC 有两种类型的方法,类方法和对象方法(也被称为实例方法) 1.类方法:以+开头,不分配内存空间(这句话,问题来了,为什么?) 什么时候分配内存空间,很显然只

对象方法的声明和实现

1.对象方法的声明 格式: 1 -(int)addNum1: (int)num1 andNum2: (int)num2; 2.特征 a:对象方法以-开头如 -(int)xx; b:对象方法只能由对象来调用 c:对象方法中可以访问当前对象的成员变量 d:调用格式 [对象名 对象方法名]; 3.示例 1 //声明没有返回值的对象方法 2 -(void)run; 3 //声明有返回值的对象方法 4 -(int)run; 5 //声明有返回值有参数的对象方法 6 -(int)run: (int)num;

直接调用对象方法的两种方式

关于直接调用方法和给对象发送消息调用方法(即perfromSelector和NSInvocation) performSelector是运行时系统负责去找方法的,在编译时候不做任何校验:如果直接调用编译是会自动校验.如果imageDownloader:didFinishWithImage:image:不存在,那么直接调用 在编译时候就能够发现(借助Xcode可以写完就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃):Cocoa支持在运行时向某个类添加方法

静态方法与实例方法,类方法与对象方法

最近看资料经常看到上面静态方法之类的说法,仔细查阅资料后总结解释如下: 最最简便的方法就是: 如果方法名字前面的单个减号(-)表明该方法是一个实例方法,也可以称呼为对象方法 如果方法名字前面是一个加号(+),则表明该方法是一个静态(static)方法,也可以称呼为类方法 再则关于静态方法与类方法是一个意思,只是很多人对于这个方法的称呼不一样罢了. 实现部分: 注意:下面的 -(id)init即为构造函数.对应的,还有一个-(void)dealloc方法用来释放资源(类似于析构函数或c#中的dis

20160122:开始学VBA:(一)、宏与VBA/(二)、VBA语句对象方法属性

从今天开始跟着<兰色幻想>视频学习VBA 宏其实就是操作步骤 录制宏是自动生成的VBA 在VB中可以自己编写 都可以通过窗体按钮指定宏 1. VBA对象 '1.工作簿       ' Workbooks 代表工作簿集合,所有的工作簿,Workbooks(N),表示已打开的第N个工作簿      ' Workbooks ("工作簿名称")      ' ActiveWorkbook 正在操作的工作簿      ' ThisWorkBook '代码所在的工作簿        '