日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C++異常處理幾大秘訣

在調(diào)用catch塊之前,把當(dāng)前異常保存在exception_storage對象中,并注冊一個專用于catch塊的異常處理程序,,C++異常處理程序必須繼續(xù)傳就能得到exception_storage對象。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供向陽網(wǎng)站建設(shè)、向陽做網(wǎng)站、向陽網(wǎng)站設(shè)計(jì)、向陽網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、向陽企業(yè)網(wǎng)站模板建站服務(wù),10多年向陽做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

現(xiàn)在重新回到C++異常處理這個主題上來。調(diào)用catch塊時(shí),它可能重新拋出異?;驋伋鲂庐惓!G耙环N情況下,C++異常處理程序必須繼續(xù)傳播 (propagate)當(dāng)前異常;后一種情況下,它需要在繼續(xù)之前銷毀原來的異常。

此時(shí),處理程序要面對兩個難題:"如何知道異常是源于catch塊還是 程序的其他部分"和"如何跟蹤原來的異常"。我的解決方法是:在調(diào)用catch塊之前,把當(dāng)前異常保存在exception_storage對象中,并注 冊一個專用于catch塊的C++異常處理程序——catch_block_protector。調(diào)用get_exception_storage()函數(shù),就能得到exception_storage對象:

 
 
 
  1. namespace my_handler   
  2. {   
  3.     __declspec(dllexport) exception_storage* get_exception_storage() throw ()   
  4.     {   
  5.         void * p = TlsGetValue(dwstorage);   
  6.         return reinterpret_cast (p);   
  7.     }   
  8. }   
  9.  
  10.  
  11. BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )   
  12. {   
  13.     using my_handler::exception_storage;   
  14.     exception_storage *p;   
  15.     switch (ul_reason_for_call)   
  16.     {   
  17.     case DLL_PROCESS_ATTACH:   
  18.         //主線程(第一個線程)不會收到DLL_THREAD_ATTACH通知,所以,   
  19.         //與其相關(guān)的操作也放在這了   
  20.         dwstorage = TlsAlloc();   
  21.         if (-1 == dwstorage)   
  22.             return FALSE;   
  23.         p = new exception_storage();   
  24.         TlsSetValue(dwstorage, p);   
  25.         break ;   
  26.     case DLL_THREAD_ATTACH:   
  27.         p = new exception_storage();   
  28.         TlsSetValue(dwstorage, p);   
  29.         break;    
  30.     case DLL_THREAD_DETACH:   
  31.         p = my_handler::get_exception_storage();   
  32.         delete p;   
  33.         break ;   
  34.     case DLL_PROCESS_DETACH:   
  35.         p = my_handler::get_exception_storage();   
  36.         delete p;   
  37.         break ;   
  38.     }   
  39.     return TRUE;   
  40. }  

這樣,當(dāng)catch塊(重新)拋出異常時(shí),程序?qū)?zhí)行catch_block_protector。如果是拋出了新異常,這個函數(shù)可以從 exception_storage對象中分離出前一個異常并銷毀它;如果是重新拋出原來的異常(可以通過ExceptionInformation數(shù)組 的前兩個元素知道是新異常還是舊異常,后一種情況下著兩個元素都是0,參見下面的代碼),就通過拷貝ExceptionInformation數(shù)組來繼續(xù) 傳播它。下面的代碼就是catch_block_protector()函數(shù)的實(shí)現(xiàn)。

在單線程程序中,這是一個完美的實(shí)現(xiàn)。但在多線程中,這就是個災(zāi)難了,想象一下多個線程訪問它,并把異常對象保存在里面的情景吧。由于每個線程都有自己的 堆棧和C++異常處理鏈,我們需要一個線程安全的get_exception_storage實(shí)現(xiàn):

每個線程都有自己單獨(dú)的 exception_storage,它在線程啟動時(shí)被創(chuàng)建,并在結(jié)束時(shí)被銷毀。Windows提供的線程局部存儲(thread local storage,TLS)可以滿足這個要求,它能讓每個線程通過一個全局鍵值來訪問為這個線程所私有的對象副本,這是通過TlsGetValue()和 TlsSetValue這兩個API來完成的。

Excptstorage.cpp中給出了get_exception_storage()函數(shù)的實(shí)現(xiàn)。它會被編譯成動態(tài)鏈接庫,因?yàn)槲覀兛梢约酥谰€ 程的創(chuàng)建和退出——系統(tǒng)在這兩種情況下都會調(diào)用所有(當(dāng)前進(jìn)程加載的)dll的DllMain()函數(shù),這讓我們有機(jī)會創(chuàng)建特定于線程的數(shù)據(jù),也就是 exception_storage對象。

【編輯推薦】

  1. C與C++中標(biāo)準(zhǔn)輸入實(shí)現(xiàn)方式上的一點(diǎn)區(qū)別
  2. C++編譯器如何對Const常量進(jìn)行分配存儲空間
  3. C++類庫設(shè)計(jì)的基本構(gòu)思與方法
  4. 玩轉(zhuǎn)C++語言的幾種方法
  5. 如何更好的進(jìn)行C++代碼編制

新聞名稱:C++異常處理幾大秘訣
文章分享:http://www.5511xx.com/article/cdcjhip.html