Gobject C語(yǔ)言庫(kù) I 對(duì)象與它的類定義

Gobject 時(shí)一個(gè)為C語(yǔ)言提供面向?qū)ο缶幊痰幕A(chǔ)庫(kù)蹲坷。 作為一門基礎(chǔ)語(yǔ)言坷剧,C語(yǔ)言在操作系統(tǒng)層面有著絕對(duì)統(tǒng)治的應(yīng)用浦夷,但是它是一門過(guò)程語(yǔ)言懊渡,在面對(duì)業(yè)務(wù)處理上,由于缺乏足夠的抽象军拟,編寫起來(lái)非常費(fèi)力剃执。為了減少這些缺陷,C語(yǔ)言生態(tài)圈也出現(xiàn)了不同的基礎(chǔ)庫(kù)懈息,幫助想使用面向?qū)ο筮M(jìn)行C語(yǔ)言開發(fā)的工程師進(jìn)行開發(fā)肾档,Gobject就是其中之一。
在面向?qū)ο蟮恼Z(yǔ)言里辫继,每一個(gè)事物或者業(yè)務(wù)會(huì)被抽象為一種類型怒见,每一個(gè)具體的事物都是這個(gè)類的實(shí)例。在聲明和創(chuàng)建一個(gè)方法通常用下面的格式:
VcamSource source=new VcamSouce(......);
在Gobject中姑宽,通常會(huì)這樣寫:
VcamSource *source遣耍;
source=g_object_new(VCAM_TYPE_SOURCE, NULL);
VCAM_TYPE_SOURCE 是一個(gè)宏定義,用來(lái)返回系統(tǒng)中注冊(cè)的VcamSource類型炮车。

在面向?qū)ο蟮恼Z(yǔ)言里因?yàn)橛袕?fù)雜的對(duì)象與類繼承管理舵变,所以通常只需要聲明VcamSource 類就可以了:
Class VcamSource{
public:
....
private:
.....

}
在C語(yǔ)言中是缺乏這些的酣溃,所以Gobject提供類自己的繼承鏈和類型注冊(cè)系統(tǒng),在Gobject中纪隙,我們通常需要聲明一個(gè)抽象類型和它的類型描述類:

#ifndef VCAM_SOURCE_H
#define VCAM_SOURCE_H

#include <glib-object.h>

#define VCAM_TYPE_SOURCE (vcam_source_get_type ())
//抽象類型
typedef struct _VcamSoure VcamSource;   
struct  _VcamSoure {
    GObject parent_instance;
};

//抽象類型的類
typedef struct _VcamSoureClass VcamSourceClass;
struct _VcamSoureClass {
    GObjectClass parent_class;
};

GType vcam_source_get_type(void);

#endif

可以看出VcamSource抽象類型其實(shí)就是一個(gè)struct 結(jié)構(gòu)體赊豌, 它包含至少一個(gè)屬性GObject parent_instance;, 這表示的是一個(gè)繼承關(guān)系: VcamSource繼承自 GObject (這個(gè)屬性必須為第一個(gè)元素)绵咱。
_VcamSoureClass 是VcamSource的類型碘饼,它用來(lái)描述VcamSource和包含這一個(gè)類事務(wù)的通用屬性或方法。它的第一個(gè)屬性是GObjectClass悲伶,也表示的是繼承關(guān)系艾恼,且 GObjectClass正是GObject的類。
在這個(gè)定義中麸锉,宏定義VCAM_TYPE_SOURCE對(duì)應(yīng)的是一個(gè)返回GType 類型的方法蒂萎,他正對(duì)應(yīng)Gobject創(chuàng)建實(shí)例的第一個(gè)參數(shù):
source=g_object_new(VCAM_TYPE_SOURCE, NULL);
VCAM_TYPE_SOURCE實(shí)際上是vcam_source_get_type()方法的調(diào)用; 這個(gè)方法主要做兩件事情:聲明一個(gè)VcamSource的Gtype類型淮椰;把這個(gè)類型發(fā)注冊(cè)到Gobject的類型系統(tǒng)里五慈,這樣才可以通過(guò)g_object_new來(lái)初始化。它的具體實(shí)現(xiàn)是在VcamSource.c文件里主穗;vcam_source_get_type的實(shí)現(xiàn)內(nèi)容大概如下:

GType vcam_source_get_type(void)
{
  static GType source_type = 0;

  if (!media_type)
  {
   //聲明一個(gè)GTypeInfo類型
     static const GTypeInfo source_info = {
        sizeof(VcamSourceClass),                    /* class structure size */
        NULL,                                                    /* base class initializer */
        NULL,                                                   /* base class finalizer */
        (GClassInitFunc)VcamSource_class_init,  /* class initializer */
        NULL,                                                  /* class finalizer */
        NULL,                                               /* class data */
        sizeof(VcamSource),                       /* instance structure size */
        16,                                                  /* preallocated instances */
        NULL,                                             /* instance initializer */
        NULL                                             /* function table */
     };
    //將GTypeInfo info注冊(cè)到Gobject的type系統(tǒng)里
     media_type = g_type_register_static(
            G_TYPE_OBJECT,                 /* parent class */
            "Media",                       /* type name */
            &media_info,                   /* GTypeInfo struct (above) */
            0);                            /* flags */
  }

  return source_type ;
}

g_type_register_static(parent_id, name, type_info, options) 用于類型的注冊(cè)泻拦,他的參數(shù)如下:
parent_id: 父類標(biāo)識(shí),Object類的標(biāo)識(shí)就是通過(guò)G_TYPE_OBJECT宏獲取
name: 類型名稱
typeinfo: GTypeInfo結(jié)構(gòu)忽媒,里面包含了對(duì)新類型的描述
options: 標(biāo)識(shí)符争拐,例如標(biāo)準(zhǔn)虛類等。
在看一下晦雨,source_info的聲明架曹,里面包含了很多內(nèi)容,我們需要了解的包含基礎(chǔ)類的初始化闹瞧,class類型的初始化绑雄,實(shí)例的初始化等等。這些方法的聲明如下:
typedef void (GBaseInitFunc) (gpointer g_class);
typedef void (
GBaseFinalizeFunc) (gpointer g_class);
typedef void (GClassInitFunc) (gpointer g_class, gpointer class_data);
typedef void (
GClassFinalizeFunc) (gpointer g_class, gpointer class_data);
typedef void (*GInstanceInitFunc) (GTypeInstance *instance, gpointer g_class);
如果要一個(gè)一個(gè)實(shí)現(xiàn)奥邮,確實(shí)也是很費(fèi)勁的事情万牺,GObject也考慮了這一點(diǎn),所以提供了一個(gè)新的宏定義洽腺,它是聲明在.c文件里:

#include "VcamSource.h"

G_DEFINE_TYPE(VcamSource, vcam_source, G_TYPE_OBJECT)   

static void
vcam_source_class_init(VcamSourceClass* class) {   //類初始化方法

}

 static void
 vcam_source_init(VcamSource* d) {   //實(shí)例初始化方法

}

 int  main(int argc, char** argv) {
     GType dtype;
     VcamSource* d;
     
          dtype = vcam_source_get_type(); /* or d = T_TYPE_DOUBLE */
        if (dtype)
             g_print("Registration was a success. The type is %lx.\n", dtype);
        else
              g_print("Registration failed.\n");
     return 0;
 }

G_DEFINE_TYPE是在.c文件里出現(xiàn)的脚粟,他做了以下的工作:

  • 聲明了一個(gè)新類型的類的初始化函數(shù),格式為<name space>_<name>_class_init 我們通常需要這個(gè)方法來(lái)注冊(cè)屬性蘸朋、掛載虛函數(shù)核无。
  • 聲明了一個(gè)新類型的初始化函數(shù),格式為 <name space>_<name>_init藕坯,我們通常在這個(gè)函數(shù)中初始化具體實(shí)例的信息团南。
  • 聲明了一個(gè)靜態(tài)變量噪沙,讓它指向新類型的類的父類。 格式為 <name space>_<name>_parent_class已慢,可用于訪問(wèn)父類中的方法曲聂。
  • 定義了獲取類ing的函數(shù)霹购,格式為<name space>_<name>_get_type ()佑惠,這個(gè)正是我們注冊(cè)類型需要的,所以GType vcam_source_get_type(void);這一行在頭文件中就可以省略了齐疙。

G_DEFINE_TYPE很顯然簡(jiǎn)化了我們的大量工作膜楷,但是要注意遵循對(duì)初始化函數(shù)的命名規(guī)范。
在面向?qū)ο蟮恼Z(yǔ)言里贞奋,通常我們需要類型映射赌厅,需要檢查某個(gè)實(shí)例是否試我們想要的類型,類似于:
source2 =VcamSoure(obj);
obj instanceof VcamSoure;
在Object里轿塔,同樣使用宏定義來(lái)實(shí)現(xiàn)前兩項(xiàng):
#defind VCAM_SOURCE(obj) ....
#defind VCAM_IS_SOURCE(obj) ....
這有需要在.h加入很多行特愿,于是為了更簡(jiǎn)潔, Gobject 提供了一個(gè)新的宏 G_DECLARE_FINAL_TYPE, 它可以做下面這些事情:

  • 聲明了一個(gè)<name space>_<name>_get_type ()方法勾缭,而G_DEFINE_TYPE包含了對(duì)它的定義揍障,所以我們實(shí)際上跟本不需要寫這個(gè)方法。
  • 定義了一個(gè)有用的宏<NAME SPACE>_<NAME>俩由,用來(lái)進(jìn)行對(duì)象的映射毒嫡。例如 VCAM_SOURCE(object)可以把普通對(duì)象類映射成我們需要的VcamSource類。
  • 定義了一個(gè)<NAME SPACE>IS<NAME>幻梯, 用來(lái)判斷是否一個(gè)實(shí)例來(lái)自于我們想要的類型兜畸。例如,VCAM_IS_SOURCE(obj), 可以判斷 obj是否是VcamSource的實(shí)例碘梢。
    于是咬摇,引入這個(gè)宏后,我們的.h文件就更簡(jiǎn)潔了:
#ifndef VCAM_SOURCE_H
#define VCAM_SOURCE_H

#include <glib-object.h>

#define VCAM_TYPE_SOURCE (vcam_source_get_type())
G_DECLARE_FINAL_TYPE(VcamSource, vcam_source, VCAM, SOURCE, GObject)

struct  _VcamSoure {
    GObject parent_instance;
};


struct _VcamSoureClass {
    GObjectClass parent_class;
};

#endif /* __VCAM_SOURCE_H__ */

但是宏G_DECLARE_FINAL_TYPE有個(gè)缺陷煞躬,它不允許有任何子對(duì)象菲嘴,相當(dāng)于用Final修飾了VcamSoure 。如果需要有子對(duì)象汰翠,就需要使用另外一個(gè)宏G_DECLARE_DERIVABLE_TYPE 龄坪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市复唤,隨后出現(xiàn)的幾起案子健田,更是在濱河造成了極大的恐慌,老刑警劉巖佛纫,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妓局,死亡現(xiàn)場(chǎng)離奇詭異总放,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)好爬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門局雄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人存炮,你說(shuō)我怎么就攤上這事炬搭。” “怎么了穆桂?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵宫盔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我享完,道長(zhǎng)灼芭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任般又,我火速辦了婚禮彼绷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茴迁。我一直安慰自己寄悯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布笋熬。 她就那樣靜靜地躺著热某,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胳螟。 梳的紋絲不亂的頭發(fā)上昔馋,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音糖耸,去河邊找鬼秘遏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嘉竟,可吹牛的內(nèi)容都是我干的邦危。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼舍扰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼倦蚪!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起边苹,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤陵且,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后个束,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體慕购,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聊疲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沪悲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片获洲。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖殿如,靈堂內(nèi)的尸體忽然破棺而出贡珊,到底是詐尸還是另有隱情,我是刑警寧澤握截,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布飞崖,位于F島的核電站烂叔,受9級(jí)特大地震影響谨胞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒜鸡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一胯努、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逢防,春花似錦叶沛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至局嘁,卻和暖如春溉箕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悦昵。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工肴茄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人但指。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓寡痰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親棋凳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拦坠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容