Symbian OS 中的Class命名約定(R類)
可以使用R類提供的函數獲取R類對象提供的資源,諸如Open(),Create() 或Initialize()等函數來分配資源和設定句柄成員變量,如果調用失敗則會返回一個錯誤碼或導致leave。R類同樣提供相應的Close()或 Reset()函數來釋放資源和重置句柄值。在同一對象上多次調用此類函數是安全的。盡管理論上清理函數可以任意命名,但絕大多數情況下都命名為 Close()。
在使用R類時一個較常見的失誤是忘記調用Close()或以為R類對象可以在析構函數中釋放自己的資源。但這會導致嚴重的內存泄露。
R類通常占用空間較小,通常除了資源句柄以外并不包含其它數據成員。R類極少有析構函數——因為清除工作通常在Close()函數中完成。
R 類可以以一個類成員或自動變量的方式在stack上存在,有些時候也可以在heap上分配。你必須確保R類在leave發生時資源可以被有效釋放,通常使用清潔棧來處理這類情況,詳細描述參見第3章。記住,如果基于heap分配一個R類自動變量,你必須在使用后確信將變量所使用資源和內存釋放完畢,通常有兩種push調用完成這樣的功能:CleanupClosePushL()(或者同類函數),用以確保資源的釋放,也可調用標準的 CleanupStack::PushL(TAny*)函數,這個函數只是在heap單元上簡單的調用User::Free()。
通常R類的成員數據要簡單的多,可以直接進行逐位復制,所以你不必期待可以在R類中看到復制構造函數和賦值操作符,否則淺表復制會引起未定義行為(undefine behavior)。比如通過逐位復制方式獲得的句柄副本將會導致資源所有權的混淆。這種情況下的未定義行為多半可以歸咎于兩個副本都試圖釋放資源而導致的。在同一對象上重復調用Close()是安全的,這是因為句柄值成員在調用Close()時復位。但是如果通過指向同一資源的兩個不同的句柄對象來調用 Close()函數,這時的情況就完全不同了。如果一個句柄對象釋放了指向的資源,那么指向該資源的另一個句柄也將會隨即失效。
如果你的類包含一個指向不可通過逐位復制進行安全共享的資源的句柄成員,則應該聲明一個復制函數來完成必要的資源復制任務。如果你希望預防對R類任何形式的復制,可以模仿C類的方式,將復制構造函數和賦值操作符聲明為private,但是不予實現。
R類的規則要多于C類和T類,所以你可以看到更多不同“物種”的R類。在Symbian OS中R類所擁有資源類型是多種多樣的——從文件服務會話的class RFs到基于heap分配內存的class RArray。
基本原則----R類對象必須通過調用Close()函數釋放資源
【編輯推薦】