国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 網絡通信 > 正文

GNOMEnclature:為GNOME2作好準備(2)

2019-11-04 21:03:40
字體:
來源:轉載
供稿:網友

  用 C 進行 OOP 編程?
  在本文中,我們將研究 Glib 對象系統,也稱為“GObject”,直到最近它還是 GTK+ 的一部分。但是在研究 Glib 2.0 中的這個新對象系統之前,我們需要解決一個更為基本的問題 - “對象系統”到底是什么以及它為何存在?究竟,C 是一種非面向對象的語言。是有可能用 C 編寫面向對象的程序,還是必須使用 C++ 編寫面向對象的程序?
  
  答案是有可能用 C 編寫面向對象的程序。但是,由于對象的概念不屬于 C 語言規范,因此需要用外部庫來提供這方面的支持。在本文中,我們使用術語“對象系統”來描述一個提供 OOP 編程所需基礎的庫,而 Glib 便是這種庫的一個示例。Glib 提供了類、繼續、引用計數、信號、接口和對象特性的 C 實現。通過使用 Glib,C 程序員就可以輕松地編寫面向對象的程序。
  
  因此,有可能用 C 編寫面向對象的程序。但是,您可能會感到迷惑:為何 GTK+ 開發人員不直接使用 C++。這里我們不討論每種可能的解釋,而只解釋為什么擁有一個用于 C 的對象系統是有意義的。其一,比起 C++,有許多開發人員更喜歡用 C。另外,由于項目或平臺的限制,可能不會選擇使用 C++ 編譯器。無論是什么原因,擁有了用于 C 的對象系統,可以使更多的潛在開發人員也進行 OOP 編程(尤其是 GNOME 編程),我們對此表示感謝。
  
  C++ 包裝器
  可以這么說,所有那些 C++ 的支持者也不必擔心 - 您也可以用 C++ 編寫 GNOME 程序。由于 C++ 是 C 語言的超集,因此您可以方便地將 C 樣式的 Glib/GTK+ 代碼和現有的 C++ 項目結合在一起。另外,您也可以使用 Glib/GTK+ C++ 包裝器。Glib/GTK+ C++ 包裝器將答應您使用本機的 C++ 類和對象與 Glib 對象交互。
  
  研究 GObject
  好了,現在您知道了對象系統的意義和用途。現在,我們將深入研究 Glib 對象系統并探究一些基本的 GObject 編程概念。直到最近,GObject 系統還是在 GTK+ 1.2.x 庫中實現的。現在,由于即將發行 GTK+ 2,該對象系統已向下移到了新 Glib 2 庫這一層。由于這樣的移動,Glib 對象系統現在就與 GUI 相關的問題完全無關了。對于我們這些喜歡在基于非 GTK+ 的程序(比如基于控制臺的應用程序和工具)中使用類和對象的人而言,是個非常好的消息。
  
  現在,讓我們把 Glib 對象系統(也稱為“GObject”)與 C++ 和 java 語言的對象系統作一下比較。首先,讓我們進行語法比較。使用 C++,您可以通過對象指針調用方法,如下所示:
  
  object->function(arg_a, arg_b);
  通過使用 C++ 對象引用,您可以輸入:
  
  object.function (arg_a, arg_b);
  Java 語言只有引用,沒有指針。Java 方法調用語法與 C++ 引用對象方法調用完全一樣:
  
  object.function (arg_a, arg_b);
  與此相反,GObject 使用標準 C 函數調用語法。其對象指針作為函數的第一個參數被傳遞。還要注重的是,為了防止名稱空間沖突,函數名用類名作為前綴:
  
  classname_function (object, arg_a, arg_b);
  您可能會感到迷惑:調用 GObject 方法與調用簡單的 C 函數到底有何區別?嗯,從 C 程序語言本身的角度而言,沒有什么區別。就 C 編譯器而言,它只是調用一個函數,而該函數的第一個參數正好是指向標準 C 結構的指針。
  
  因此您的 C 編譯器甚至不知道我們正在編寫面向對象的程序。但是,別讓這個事實愚弄了您,讓您誤以為 GObject OOP 編程只是將良好的舊式 C 編程進行了一番改頭換面。GObject 在幕后確實作了許多工作,答應您創建現有類的子類、創建類的接口(我們將在本文的后面對此進行討論)等等。不過這個 OOP 的所有功能都旨在與標準的 C 編程構造完全兼容。
  
  關于 GObject 方法調用,這里還要說明另一件重要的事。當(您調用方法時)將某個對象傳遞給類函數時,需要對該對象進行數據類型轉換以便與您正在調用的函數的預期類型相匹配。例如,假如您想將 GtkButton 對象傳遞給帶有 GtkWidget 參數的函數,您就要編寫:
  
  gtk_widget_show (GTK_WIDGET (button));
  GObject 接口
  除了對 GObject 進行的許多改進之外,Glib 2 還引入了稱作“接口(interface)”的 OOP 概念。為了理解接口是什么,讓我們研究一個示例。
  
  假設我們想要為應用程序創建一個 Pegasus 對象。由于飛馬(pegasus)是神話中有羽翼的馬(horse),OOP 編程的習慣做法就是創建一個新 Pegasus 類,它使用 Horse 類作為其父類。然后,我們將給新類添加必要的代碼以支持它擁有“羽翼”這一特性。在本例中,創建 Pegasus 作為 Horse 的子類很有意義,因為它表示了這兩個類之間的關系。
  
  但是,假如我們擁有多種不相關的類,比如 Horse、Car 和 House,并且我們希望使它們都可能進行通信。這個新能力與它們彼此的關系無關 - 事實上,這三個類對于我們而言根本沒什么關聯。但我們希望它們都支持與通信相關的新功能。我們該怎么辦呢?
  
  接口給這個問題提供了解決方案,它答應我們給全異類添加公共功能。因此回到上面的示例,我們只要為 Horse、Car 和 House 類編寫“Talk”接口。忽然之間這三個不相關的類都“能夠通信”了,并且能夠使用我們所創建的與通信相關的新函數。并且這些與通信有關的新函數使用“Talk”接口本身與我們的對象“愉快”地進行交互。因此,由于接口,這三個不相關的類現在“講同一種語言了”。
  
  在 Glib 中,您可以為一個類創建任意數量的接口。因此,假如我們為 House 類創建了一個 Talk 接口,我們可以如下定義 say() 函數:
  
  void say (Talk *mytalk, const char *myphrase);
  然后,我們可以調用 say() 函數,將 myhouse 變量的數據類型轉換成“Talk”接口。
  
  say (TALK(myhouse), "hello there!");
  可以在 GTK+ 2 的 GtkEditable 接口中找到更加切實可信的接口示例(請參閱參考資料以獲取鏈接)。文本窗口小部件和條目窗口小部件都實現了這個接口。
  
  GObject 信號
  一般而言,由事件驅動的 GUI 程序包含一個主循環。在該循環中,程序一直等待從 X 服務器發出的新消息。這些消息(稱為事件)由程序進行解釋,并答應程序對用戶選擇菜單項、單擊按鈕等操作作出反應。
  
  信號除了將對象相互連接之外,與事件非常相似。它們答應對象在不需要顯式的事件循環的情況下自動對另一個對象狀態的變化作出“反應”。只需要將一個對象的信號連接到另一個對象的方法。然后,當第一個對象“發出”信號(由于狀態的內部變化)時,第二個對象“捕捉”該變化并作出適當的反應。之所以不需要事件循環,是由于信號是用回調實現的 - 發出信號的結果只是調用一個 C 函數。信號是一種有效和靈活的“粘合劑”,它們把程序中的對象“粘合”在一起。
  
  事實上,假如您閱讀過以前的 GNOMEnclature 專欄文章,您將看到我們擁有相當多類似于下面這樣的示例代碼行:
  
  g_signal_connect (G_OBJECT (window), "destroy", gtk_main_quit, NULL);
  在上面的代碼段中,我們將主窗口對象的 "destroy" 信號連接到 gtk_main_quit() 函數。由于 g_signal_connect(),當我們的窗口發出 "destroy" 信號時(當該窗口關閉時),我們的程序將自動退出。假如您過去曾經編寫過事件驅動的程序,那么我認為您會發現,對于設置顯式事件處理循環這一常見做法,使用信號是一個令人耳目一新的變化。
  
  這樣,我們了解了如何將信號連接到標準的 C 函數。但是我們該如何將這同一個信號連接到某個特定對象的方法呢?很簡單 - 只要使用下面這個模板
  
  g_signal_connect (G_OBJECT (window), "destroy", classname_function, object);
  只要用要調用的方法替換 classname_function,并用方法應該操作的對象指針替換 object。要了解有關信號的更多信息,請查閱本文的參考資料一節以獲取一些不錯的鏈接。
  
  但是,請注重,Glib 和 GTK+ 2.0 對信號方面作了一些更改。盡管基本概念并沒有更改,但信號系統已從 GTK+ 2.0 遷移到 Glib。這產生了一個便利的副作用:可以在非 GUI 應用程序中使用信號。假如您正在編寫新 GNOME 2.0 代碼,則應當使用 Glib 新的 GSignal 類;GTK+ 2.0 信號仍然存在,但只是包含了幕后使用 Glib 的 GSignal 的“包裝器”。
  
  盡管存在所有這些變化,但 Glib 信號(用 g_signal_ 作為前綴)總體上還是非常類似于 GTK+ 中對應的信號(用 gtk_signal_ 作為前綴)。但是,假如您已經創建了或正打算創建自己的定制信號,則應當閱讀 GObject GSignal 參考文檔(請參閱參考資料)以了解可能適用于您的某些變化。
  
  結束語
  既然我們研究了 GObject 基礎知識,您應當已經把握必要的基本概念,可以開始您的 GNOME 編程生涯了。咱們在下一篇“GNOMEnclature”專欄文章中再見,繼續為 GNOME 2 平臺作預備。到時候再見!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 怀柔区| 普宁市| 会同县| 连平县| 靖州| 余姚市| 长海县| 仁怀市| 天祝| 安新县| 房产| 清原| 昌乐县| 梓潼县| 临沧市| 石屏县| 绵竹市| 延吉市| 化德县| 赫章县| 湘潭市| 武夷山市| 和林格尔县| 米易县| 辽阳县| 延津县| 龙岩市| 罗定市| 宾阳县| 新建县| 丰台区| 武陟县| 获嘉县| 虞城县| 安义县| 水富县| 阿荣旗| 叙永县| 蒲城县| 和顺县| 京山县|