[原創(chuàng)文章歡迎轉(zhuǎn)載,但請(qǐng)保留作者信息]
Justin 于 2010-05-25
到了七七四九章,大師已經(jīng)帶領(lǐng)我們走進(jìn)了全書的第八部分:定制new和delete。往往只有掌握了程序背后的內(nèi)存管理機(jī)制,才能真正做到對(duì)程序的控制。上課上到這里,恭喜你慢慢在進(jìn)步了。
Item49要講的是當(dāng)new失敗時(shí),負(fù)責(zé)異常處理的new handler程序。大師說(shuō)一個(gè)合格的new handler應(yīng)該具備下面的特征:
- 可以“擠”出更多的可用內(nèi)存。本來(lái)喊你來(lái)就是因?yàn)闆]有內(nèi)存可以用,這個(gè)算是個(gè)最基本的要求了。
- 當(dāng)無(wú)法安排出更多可用內(nèi)存時(shí),要有下一步的解決方案。比如說(shuō)找另外一個(gè)人來(lái)幫忙(通過(guò)set_new_handler來(lái)設(shè)置調(diào)用另一個(gè)new handler),或是變身為超人(通過(guò)改變函數(shù)自身的行為來(lái)進(jìn)一步分配可用內(nèi)存,說(shuō)穿了就是類似下面的處理過(guò)程,當(dāng)然實(shí)際并沒有那么簡(jiǎn)單)
if?(!?failed)
{
???//do?the?normal?new?exception?handling
???if?(?cannot_make_more_memory_available?)
??????failed?=?1;
}?else?{
???//do?another?way?around?to?get?more?memory
}
- 應(yīng)該可以“卸載”new handler。也就是說(shuō)可以禁止對(duì)new失敗時(shí)進(jìn)行任何處理,或者說(shuō)是關(guān)掉new handler,此時(shí)new的失敗會(huì)直接拋出異常。
- 應(yīng)該在無(wú)法安排更多可用內(nèi)存時(shí)拋出bad_alloc或類似的異常,以讓申請(qǐng)內(nèi)存的家伙知道這次沒有面包吃了。
- 不會(huì)返回,一般而言,意味著該函數(shù)應(yīng)該以abort或是exit自我了斷。
在C++中可以專門為某個(gè)類實(shí)現(xiàn)其專屬的new handler,只要正確利用set_new_handler()就可以了。
接下來(lái)大師寫了一個(gè)通用的模板類,幫助另外一個(gè)類實(shí)現(xiàn)安裝/卸載特定的new handler。它的設(shè)計(jì)很簡(jiǎn)單,在調(diào)用new之前安裝指定的new handler,調(diào)用結(jié)束后卸載并恢復(fù)原先的全局handler。安裝new handler的函數(shù)、重載的new函數(shù)以及用于暫時(shí)保存new handler的函數(shù)指針都是靜態(tài)的(static),這樣做的目的是可以基于模板類的每個(gè)模板參數(shù)生成一套專屬的實(shí)例。例子在書上,就不畫蛇添足了。