Symbian手记【一】 —— Symbian命名法
生活随笔
收集整理的這篇文章主要介紹了
Symbian手记【一】 —— Symbian命名法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【一】 Symbian命名法
每個美感尚存的C++ coder,第一次看到Symbian C++的程序,第一反應是:這鬼代碼怎么縮進的?接下來,所有人會有疑問應該是:函數和類上的亂七八糟的前后綴是啥意思? 娃再丑也是爸媽生的,生成這模樣雖然很無奈,但確實也是事出有因。在我看來,Symbian命名法的核心出發點,就是為了更好的內存資源管理。C++的人肉內存管理模式,在給人以控制到字節的快感的同時,也帶了了麻煩到每行代碼的煩惱。命名法,就是Symbian設計者憋出來用來輔助管理內存資源的方式之一。類命名
Symbian的類,通常都帶著一個字母的前綴,比如C、M、T、R、H等等。 所有從CBase派生而來的子類,都以C開頭,形如Cxxxx。每個正確設計的,非抽象(不可實例化)的C類,都只能在堆上分配。為了保證這一點,每一個可實例化的C類,都應該按照Symbian的二階段構造模式。但當然,這可以有意外。比如一些派生自CCoeControl的控件對象類,會需要從Resource文件中構造類的成員對象(而不僅僅通過二階段中的ConstructL方式來構造),這使得它可能不適合按照二階段構造的方式來封裝。 做過.Net或者Java的人應該都明白,保持一個單一根的類型系統有什么好處,.Net在沒有泛型的日子里,就是通過這個共根來實現一些基礎的容器和方法。但這個好處,在C++,尤其是Symbian C++中體現的并不明顯。因為C++有void *(在Symbian中華麗的轉身為TAny *),有模板,可以來做一些類似的事情。更重要的,在Symbian C++中,為了節約空間,把虛表的RTTI項給精簡掉了,使得Symbian C++的類喪失了dynamic_cast的能力,從而導致整個Symbian在運行期的動態識別能力,很是孱弱。 所以說,之所以要從CBase類進行派生堆上對象,很重要的一個原因,就是為了內存管理。CBase做了一件很重要的事情,就是將拷貝構造函數和賦值函數設置成了私有。這意味著,所有從CBase派生的子類,都默認被閹割了一刀,失去了拷貝構造的能力。這是為了提醒所有使用者,C對象的淺拷貝是不受歡迎的,如果你想提供該對象的拷貝功能(要深拷貝,不要淺...),往往是利用一些CloneL之類的接口來實現,保證行為的統一性。C的類們,都涌向了堆中,棧上的活,留給了T類來完成。T類沒有什么特殊的繼承結構,每個T類,需要可以隨意的在堆上或者棧上分配。大部分時候,它們該待的地方是棧,在棧上分配,并可以快速拷貝,一旦被析構,所以資源被釋放,生不帶來死不帶走不留下一點殘渣。因此,它們不應該包含大塊的數據對象,但卻可以擁有很復雜的接口,增加操作的便利性。比如,TRgb、TRect之類的系統類,就是典型的人小鬼大的代表人物。但T類不是C++的old plain類,它可以有繼承結構,比如Symbian中描述符的那一堆堆T類,就擁有復雜的繼承結構。
但世界是殘酷的,有的類,偏偏就是投錯了胎,搞得人不人,鬼不鬼。HBuf,就是此中代表。為了保持隊形,維系接口,HBuf派生自TDesC,用以表示分配在堆上的Symbian描述符(就是字符串...)。但與一般T類不同,因為其占用空間動態變化,它必須在堆上分配,所以喪失了叫T的權利;另一方面,為了接口,它派生了T類,在排斥多根的C++中,它就不能夠在從CBase派生了(繼承的局限性,可見一斑),被斷了叫C的后路。于是,就帶上了H的特殊帽子,表示其在堆上分配,但不茍且于C類的屋檐下。
R類,換成通俗的描述,就是句柄類。它天生為了管理資源而存活,R類本身很簡單,通常在棧上分配,可以拷貝,在這一點非常接近于T類。但與T類不同的時,R類往往帶有某個堆對象的指針,指向文件之類的資源,或者是大塊的堆數據對象。它析構的時候,默認是不析構這個指向的對象的,而是提供了一些類似于Close,Release之類的接口,需要人肉手動釋放。有的T類也是指向另一塊堆或者棧區域的,比如TPtr類。這兩者一個本質的區別在于,T類指向的對象,不是它自己分配,它只是提供一個快捷方式,并不管指向對象的死活;而R類指向的資源,往往是自己本身或者另一個同類分配的資源,R類對象指向的資源,必須從這個R類的對象構造,從這個R類的對象析構(兩個對象可以不同,但類是一致的)。
在Symbian C++中,還有一些類,不涉及任何內存資源。一個就是接口類,它們以M開頭,相當于.Net的Interface,是一個純虛類。每個Symbian中的類,可以派生自若干個M類,但僅僅能從一個有內存資源的對象那里進行分配。理論上,作為一個純虛類,應該提供一個虛的析構函數,但在Symbian C++中,這往往是不需要的。因為在一個沒有RTTI的世界里,只有第一個被繼承的接口才有可能成功析構所有對象。比如一個類,形如 class A : public Cxxx, public Mxxx。只有用Cxxx接口才能管理資源,對Mxxx接口進行delete,完全沒有辦法釋放全部資源(除非Cxxx里面沒有任何數據...)。而Symbian的堆對象往往派生自CBase,所以,不可能從一個M類來析構對象,這個析構函數成不成虛,就是無關緊要的事情了。 另外一個不含任何資源的類,就是靜態類了,在Symbian C++中它們沒有任何前綴,是唯一不戴帽子的家伙。這個和.Net的static class一樣,只包含一堆的靜態方法,需要屏蔽所有構造、析構、拷貝接口(要沒有這個閑工夫,不屏蔽也無所謂了...)。雖然,C++有函數,但出于對面向對象的熱衷,使用這樣的靜態類,還是很值得鼓勵的。。。
函數命名
在Symbian中,類是戴帽子的,函數則是穿褲子的。在Symbian的函數(包括成員和非成員函數)中,常有兩種后綴,一個是L,另一個是LC。L,就是告訴你,這個函數可能Leave,換人類可知的語言描述,就是這個函數會拋出異常,需要謹慎處理。L是有傳遞性的,如果在調用該函數的地方對此L不理不睬放任其Leave,那么,在此調用函數后面,也需要添加一個L。 除了L,還有跟進一步的LC。這通常都是構造性的函數,它告訴你,它構造的過程中,不但可能Leave,并且分配的對象處于清理棧中。這是一個接近于語法糖的功能,如果在本函數中的后續部分需要調用被構造對象的相關接口,應該用LC,然后自己pop,而不是L。其他命名法
還有一些對象,是會被帶著前綴的。比如對象的成員變量,都帶著前綴i;函數參數,都帶著a(如果后面是原因字母開頭,則需要用an,*_*)。在成員變量加前綴,這是常用的手段,可以和成員變量區分開了,幫助節約命名一個變量的腦細胞。但對函數形參加前綴,就是一件很詭異的事情了,剖有畫蛇添足的藝術氣息。 在Symbian中,所有的常量,都應該是K開頭的,包括定義的const量,_LIT定義的字符常量等等。而枚舉類型,同屬于T類型,以T開頭,其中的枚舉值,則是以E開頭。給這些類型的東西建立命名法,是常見的手段,只是Symbian不走尋常路,命名方式上不屑于與別人茍同。。。結語
簡而言之,Symbian制定了一套復雜的命名法規則,期待以此來規范化內存管理等操作。但世界的殘酷在于,一個沒有強制的標準,是不可靠的。命名法是一種弱約束的東西,工期趕的再急,也不可能無視編譯和運行時的錯誤,但卻可以無條件的忽視命名規則。并且,命名法是有強烈的破窗效應,一旦某一個函數沒有合理的添加L,所有直接和間接調用它的函數,都可能會錯誤使用它,從而埋下隱患。況且,Symbian的命名法也算是枝繁葉茂了,很容易讓人看不清楚端倪,不知不覺的就用錯了,一個團隊每個人在這上面犯一些錯誤,到最后命名法就完全喪失了效能。不過,就算是環境惡劣,對于個人而言,還是應該嚴于律己的,不論如何,不要輕易拋棄正確命名,這樣,才可能造福大家。。。總結
以上是生活随笔為你收集整理的Symbian手记【一】 —— Symbian命名法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 湖北省高职计算机本科学校有哪些,盘点最新
- 下一篇: 程序员是青春饭吗?30岁后的发展方向和突