Symbian OS 中的Class命名約定(C類)
C前綴[1]的類皆由CBase類(定義于e32base.h)派生(直接或間接)。CBase類通過繼承確保了所有的C類都具有如下兩個(gè)特征。
首先,CBase有一個(gè)虛析構(gòu)函數(shù),所以C類對(duì)象都應(yīng)該通過刪除CBase的指針進(jìn)行銷毀。通常清潔棧就使用這一方法,在將C類對(duì)象壓入清潔棧時(shí)需要重載調(diào)用CCleanupStack::PushL(CBase* aPtr)函數(shù)。
如果對(duì)對(duì)象調(diào)用CCleanupStack::PopAndDestroy()(或在發(fā)生leave時(shí)),對(duì)象會(huì)通過刪除CBase指針被刪除。 CBase 的虛析構(gòu)函數(shù)確保了對(duì)派生類的析構(gòu)函數(shù)的正序調(diào)用(由***層派生類起,逐層向上調(diào)用)。所以應(yīng)當(dāng)認(rèn)識(shí)到,C類在這一點(diǎn)上有別于T類,它們通常都有一個(gè)析構(gòu)函數(shù)。
還有一點(diǎn)需要注意的是,如果需要將非CBase的派生類壓入清潔棧,將重載 CCleanupStack::PushL(TAny*aPtr)函數(shù)而不是CCleanupStack::PushL(CBase* aPtr)。正象上面說的那樣,當(dāng)調(diào)用PopAndDestroy()或發(fā)生leave時(shí),將會(huì)釋放對(duì)象的內(nèi)存但并不會(huì)調(diào)用對(duì)象的析構(gòu)函數(shù)。所以如果不直接或間接地繼承CBase類,即使你的基類有一個(gè)虛析構(gòu)函數(shù),你的類的對(duì)象也不會(huì)象你所期待
1這里可能讓你覺得詫異,'C'表示'Class','C class'多少讓人覺得有點(diǎn)羅嗦,但以T類的"Type'作為參照系,'C class'是一個(gè)正確的表示方法。
的那樣可以順利清除。
CBase 類及其派生類的第二個(gè)特征,是當(dāng)***在heap上建立對(duì)象時(shí),將重載new操作符來(lái)對(duì)對(duì)象進(jìn)行零初始化。這意味著C類對(duì)象的所有數(shù)據(jù)成員在***創(chuàng)建時(shí)皆為零。而不必由你親自在構(gòu)造函數(shù)中顯式地進(jìn)行這項(xiàng)工作。因?yàn)閟tack的分配不使用new操作符,所以零初始化也就不會(huì)在stack對(duì)象上發(fā)生作用。這間接的導(dǎo)致了基于heap的零初始化和基于stack的非零始化的不同行為。由于這一原因,特別就leave發(fā)生時(shí)的清潔處理而言,C類對(duì)象必須在heap上進(jìn)行分配。
顯而易見,基于heap的對(duì)象在失去使用價(jià)值后必須銷毀。C類對(duì)象通常作為另一個(gè)類的指針成員或局部指針變量使用。如果C類對(duì)象是一個(gè)成員變量,則應(yīng)在C 類的所有者的析構(gòu)函數(shù)中使用delete操作來(lái)銷毀。如果是一個(gè)臨時(shí)性的局部指針變量,那么必須在任何可能產(chǎn)生leave的代碼之前將其壓入清潔棧——否則一旦發(fā)生leave就會(huì)導(dǎo)致內(nèi)存泄露。第3章將詳細(xì)論述這一問題。
如果觀察一下e32base.h,你將注意到CBase聲明了一個(gè)private的復(fù)制構(gòu)造函數(shù)和賦值運(yùn)算符。這是一個(gè)較常用的策略,可以防止用戶意外地 C類對(duì)象進(jìn)行淺表復(fù)制(shallow copy)。如果一定要對(duì)你的類進(jìn)行復(fù)制操作,那么必須顯式聲明并定義一個(gè)public復(fù)制構(gòu)造函數(shù)和賦值運(yùn)算符,因?yàn)樵诨愔袕?fù)制構(gòu)造函數(shù)和賦值運(yùn)算符被聲明為private,所以不能進(jìn)行隱式調(diào)用。但是,一個(gè)深層復(fù)制(deep copy)有可能導(dǎo)致潛在的leave發(fā)生,而就C類的本性而言,你又決不能允許在一個(gè)構(gòu)造(或析構(gòu))函數(shù)中產(chǎn)生leave(參見第4章)。所以如果需要為C類提供復(fù)制操作,就不要定義并實(shí)現(xiàn)一個(gè)公共的復(fù)制構(gòu)造函數(shù),而應(yīng)加入一個(gè)允許leave的函數(shù),例如CloneL()或CopyL(),這樣既遵守了 C類的規(guī)則同時(shí)又完成了復(fù)制操作的任務(wù)。
因?yàn)榇蠖鄶?shù)C類往往不足以直接提供逐位復(fù)制,所以***避免隱式復(fù)制,這是派生于CBase的另外一個(gè)優(yōu)點(diǎn)。CBase類中的復(fù)制構(gòu)造函數(shù)和賦值操作符的private聲明意味著你可以不必在每個(gè)C類中都親自聲明它們,以防止這種具有潛在危險(xiǎn)的淺表復(fù)制。
基本原則----C類對(duì)象必須基于heap分配
【編輯推薦】