《C++沉思錄》 第六章 句柄 第一部分

      簡單回顧一下第五章節,Andrew Koening向我們提出了一個問題,在一個繼承體系中,如何設計一個容器可以容納各個不同的子類對象。顯然無法使用基類對象數組,如果是抽象基類,沒有辦法進行實例化。很自然的我們容易想到可以使用基類指針,但這樣對象內存管理便交於用戶了,容易造成很多麻煩問題。爲了解決此問題,Koening使用了代理類。

     什麼是代理類呢,簡單來說,就是封裝了基類指針並可以提供所有功能接口的類。在代理類的構造過程中,使用對象的指針初始化代理類的基類指針成員,並在析構函數中釋放代理的對象內存。仔細思考一下,其實一個代理類對象可以代理多個類型不同的對象,但是否會有用,現在仍在思考中。

     好了,進入第六章 句柄,Koening又提出了一個問題,代理類的複製會造成其代理的對象的複製,這個在很多場合下是不合理的,如何可以具有代理功能,而又避免不必要的複製呢,"句柄類" is the answer.  那麼句柄類應該具備些什麼呢,首先句柄類應該和代理類一樣具備對綁定對象的生存控制權。這個取決於句柄類的構造函數,要不然句柄類可以直接構造其綁定的對象,要不然就需要一個存在的對象的來創建一個副本並綁定到副本上。 到目前爲止,句柄和前面的代理沒什麼區別。

     句柄區別於代理的是:允許多個句柄綁定到同一個對象上,當複製句柄的時候,並不發生對象的複製。這個的常見應用場景是我們以一個句柄作爲函數的參數,我們可以做到只複製句柄而不復制對象,怎樣做到呢。來看一個簡單模型:A, B, C三個家庭在同一小區,在一天內都向物業的維修人員提出了維修請求,維修人員D負責三家的維修工作。A,B, C在這一天都與D建立了聯繫(電話預約之類的),當D給A維修完時,A對D說:“你可以走了”,但D並沒有真正的離開小區,他還需要給B,C家進行維修。 同樣,假設三個句柄A,B,C都與D進行了綁定,當A使用完畢說釋放掉D的時候,D當然可以釋放掉也可以不釋放掉,因爲D的工作還有B,C。這個就相當於維修人員給A維修完畢後,返回家,接着再返回來給B,C維修,我想維修人員不會那麼傻,來回跑。因此D在這種情況下不會釋放,但是不釋放得有依據,我什麼時候釋放。維修人員自己有記錄的,誰打了電話,當所有的電話記錄中的維修處理完畢後,維修人員才離開。但如果維修人員離開後,再有人打電話過來,他當然需要再返回去。因此對象D需要有個記錄去維護以便知道什麼時間釋放自己。那這個記錄爲什麼需要對象來維護呢,很簡單,A家庭不關心維修人員是否需要給其他家庭進行維修,我只關心你需要給我維修。因此記錄只能由維修人員來維護。

     回到對象D,對象D需要維護一個記錄來確定自己是否要釋放掉,那這個記錄需要些什麼麼,需要關心誰綁定了我麼,不需要。這個多少跟我們前面的場景有所差別,維修人員需要在收到通知後主動去提供服務,而我們的對象不需要,我們是被使用者。對於對象來說,誰來使用我沒有太大差別。因此不需要關心誰來使用對象,對象只需要一個計數,增加了一個使用者,計數增加1,使用完畢,計數減一,如果計數爲0說明沒有人使用了,我可以去了。

    koening給我們講敘的計數要稍複雜些,如果我們的對象類是我們剛設計的,那我們可以加入計數。但是對於一個已經存在的對象類,我們往往不會修改其實現,這個時候就需要定義一個新類來容納原有對象和計數。好了理清這個思路,後面koening後面就講了如何實現以及一些技巧性東西。不在贅敘。

 

      

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章