1. 程式人生 > >GObject 子類私有屬性的外部訪問

GObject 子類私有屬性的外部訪問

之前,寫了一篇 GObject 勸學的文章 [1],還有兩篇有關 GObject 子類物件資料封裝的文章 [23]

雖然,建立一個 GObject 子類物件需要一些輔助函式和巨集的支援,並且它們的內幕也令人費解,但是隻要將足夠的信任交託給 GObject 開發者,將那些輔助函式和巨集當作“語法”糖一樣享用,一切還是挺簡單的。至於細節,還是等較為全面的掌握 GObject 庫的用法之後再去挖掘!

現在,我們基本上知道了如何將資料封裝並藏匿於 GObject 子類的例項結構體中。本文打算再向前走一步,關注如何實現在外部比較安全的訪問(讀寫)這些資料。

簡單的做法

像下面這樣的雙向連結串列資料結構:

?
1 2 3 4 5 6 7 8 9 10 11 typedef struct _PMDListNode PMDListNode; struct _PMDListNode {          PMDListNode *prev;         
PMDListNode *next; };   typedef struct _PMDList PMDList; struct _PMDList {          PMDListNode *head;          PMDListNode *tail; };

現在,我們希望能夠安全訪問 PMDList 結構題的兩個成員,即連結串列的首結點指標 head 和尾結點指標 tail,以便進行一些操作,例如將兩個雙向連結串列 list1 和 list2 連結到一起。

所謂安全訪問,意味著不要像下面這樣簡單粗暴:

?
1 2 3 /* 將 list1 與 list2 連結在一起 */ list1->tail->next = list2->head; list2->head->prev = list1->tail;

而應當委婉一些:

?
1 2 3 4 5 6 7 PMDListNode *list1_tail, *list2_head;   list1_tail = pm_dlist_get (list1, TAIL); list2_head = pm_dlist_get (list2, HEAD);   pm_dlist_set (list1, TAIL, NEXT, list2_head); pm_dlist_set (list2, HEAD, PREV, list1_tail);

這樣委婉的訪問,有什麼好處?答案很簡單,可以將資料的變化與程式的功能隔離開,資料的變化不影響程式的功能。

試想,如果有一天,上述 PMDList 結構體的設計者使用 GObject 子類化的方法將雙向連結串列定義為建 PMDList 類的形式,並且將連結串列的首結點指標 head 與尾結點都隱匿起來,那麼上述的那個簡單粗暴的資料訪問方法便失效了。更糟糕的是,PMDList 類的設計者明知道很多人會受到這種資料變化的影響,對此也毫無辦法。

如果 PMDList 結構體的設計者提供了 pm_dlist_set 與 pm_dlist_get 函式,那麼即便設計者基於 GObject 子類化的方式定義了 PMDList 類,他只需要修改 pm_dlist_set 和 pm_dlist_get 函式,便可以讓上述那種委婉方式訪問 PMDList 結構體成員的程式碼不會受到任何影響。

既然 pm_dlist_set 與 pm_dlist_get 函式這樣有用,我們可以像下面這樣實現它們。

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 typedef enum _PM_DLIST_PROPERTY PM_DLIST_PROPERTY enum _PM_DLIST_PROPERTY {          PM_DLIST_HEAD,          PM_DLIST_TAIL,          PM_DLIST_NODE_PREV,          PM_DLIST_NODE_NEXT };   PMDListNode * pm_dlist_get (PMDList *self, PM_DLIST_PROPERTY property) {          PMDListNode *node = NULL;

相關推薦

GObject 私有屬性外部訪問

之前,寫了一篇 GObject 勸學的文章 [1],還有兩篇有關 GObject 子類物件資料封裝的文章 [2, 3]。 雖然,建立一個 GObject 子類物件需要一些輔助函式和巨集的支援,並且它們的內幕也令人費解,但是隻要將足夠的信任交託給 GObject 開發者

python私有屬性訪問控制

不同於c++,java這些編譯型語言Pyt,hon根本沒有訪問控制,只有變數名壓縮…這麼說的要麼是大神,要麼是像我這樣鑽牛角尖的… 首先看一段程式碼,我們想物件的一個屬性只能被這個這個物件(即通過類裡定義的方法來訪問)所訪問時,通常會這麼寫: class P

GObject 物件的私有屬性模擬

轉載自 http://garfileo.is-programmer.com/2011/2/28/data-hiden.24848.html 上一篇文章“使用 GObject 庫模擬類的資料封裝形式”講述了 GObject 子類化過程,本文以其為基礎,進一步講述如何對資料進行隱藏,即對面向

php中外部訪問私有屬性的方法

我們都知道,類的私有屬性在類外部是不可訪問的,包括子類中也是不可訪問的。比如如下程式碼: <?php   class Example1{      private $_prop = 'test';  }    $r = function(Example1 $e){ 

class中的私有屬性訪問

__init__ 訪問 self. print nbsp 如何 私有 get 一個 在類中的私有屬性設置:  class Name():   __init__(self):      self.__name = ‘arnol‘` 如何查看:   1,在類中定義一個方法:

MyBatis 獲取屬性

這裡有個model類:基類:public class user { public int getId() { return id; } public vo

Java 反射呼叫屬性和方法(包含父私有屬性和覆蓋重寫的方法等)

前面介紹了,反射呼叫類的構造方法來建立類的例項物件。一個類的結構包含方法(構造,靜態,非靜態)和屬性(靜態和非靜態)。按照迴圈漸進的方式,接下來,介紹反射類中屬性和普通的方法。 在這裡簡單介紹,反射呼叫屬性和方法會用到的新類,Method類和Field類。

java中介面的屬性、方法的預設修飾符和屬性訪問修飾符的區別

介面中的屬性的預設是public static final 、方法是public abstract 類的成員變數或成員方法宣告為預設許可權,則其是包級可見,同一個包內的類可以訪問到這個屬性或方法fri

函式指標、回撥函式與 GObject 閉包 GObject 物件的析構過程 GObject 的訊號機制——概覽

手冊所述,GObject 訊號(Gignal)主要用於特定事件與響應者之間的連線,它與作業系統級中的訊號沒有什麼關係。例如,當我向一個檔案中寫入資料的時候,我期望能夠有一個或多個函式響應這個“向檔案寫入資料”的事件,這一期望便可基於 GObject 訊號予以實現。 為了更好的理解 GObje

PHP面向物件----(私有屬性訪問方法)

<?php //對私有屬性的訪問方法一(系統方法) class A { private $name = 'hello world'; function __set($prop

[c++]私有的虛擬函式,多型問題

       執行時也不會報錯。因為函式的訪問許可權應該只在編譯期有,編譯成機器碼就已經沒有訪問許可權控制了。所以最終,應該是可以編譯,也可以執行。這個特點等於為我們提供了一個強制使用子類的程式設計師必須使用基類的指標來呼叫子類實現的函式,而達到多型的目的,因為子類的函式,

引用指向物件屬性

父類引用指向子類物件指的是: 例如父類Animal,子類Cat,Dog。其中Animal可以是類也可以是介面,Cat和Dog是繼承或實現Animal的子類。 Animal animal = new Cat(); 即宣告的是父類,實際指向的是子類的一個物件。 那這麼使用的優點是什麼,為什麼要這麼

Java 反射調用屬性和方法(包含父私有屬性和覆蓋重寫的方法等)

tst set clas declared method ces arr tails net public static void main(String[] args) { //需要訪問的類 PaymentRequest PaymentRequest tPay

GObject [3] 物件私有屬性的模擬-隱藏

1、隱藏什麼,為什麼要隱藏? 隱藏的就是非類型別資料,也就是不是我們要封裝成類的資料。 隱藏以後就簡化了.h檔案,.c檔案複雜了,使用類的人當然是希望他要看到的.h檔案越簡單越好。而.c這部分程式碼通常是第三方並不關注的。 2、如何隱藏? 方法很多,這裡寫出兩種。

Java訪問私有成員變量

私有成員變量 數列 屬性和方法 訪問 標識符 不同的 不可見 重載 一份 /**子類會繼承父類所有的屬性和方法。 * 但是根據不同的權限標識符,子類不可見父類的私有變量,但可以通過父類的公共方法訪問私有變量 * 所以對於重名變量,子類和父類都各有一份。 * 對於子類和父類中

訪問私有屬性

-i cti func hack bject ces pri path RF 如何訪問類的私有屬性? 下面以 TPathData 為例,它有一個私有屬性 PathData,儲存了每一個曲線點,但一般無法修改它,需要利用下面方法,才能訪問修改(若有更好的方法,歡迎分享): 一

關於訪問和修改父屬性值的網上答案搜查+個人理解

java 怎樣永久改變父類中公有屬性的值 不太明白你要說什麼,類中的屬性一般都是private?,保證封裝性,如果你要用public?,也沒任何問題。你要在子類中該父類的屬性,不是有getter和setter?的方式改啊。 格外說一句面向物件是把所有的都看成一個物件,你肯定是子類例項化,傳參的時候可以用g

python 直接訪問私有屬性或方法

# 內容:直接訪問類的私有屬性或者方法 # # 環境:py 3.6.2 # 1 - 訪問類的私有屬性或者方法. 首先我們定義一個包含私有屬性的類 class Private(): def __i

Python中直接訪問私有屬性私有方法

首先我們定義一個包含私有屬性的類 class Foo(object): def init(self): self.__private = 521 例項化並嘗試訪問__private私有屬性, private_out = Foo() private_out.__p

java中子是否可以訪問私有屬性

首先子類是無法繼承父類的私有屬性,也無法直接訪問父類的私有屬性。 但如果父類中有對私有屬性的get和set的方法,而且是public的修飾的方法, 子類在繼承父類的同時,也繼承了帶有public修飾的set和get方法,所以可以通過以下方式子類可以訪問到父類的私有屬性。