自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++異常處理幾大秘訣

開發(fā) 后端
也許大家對與C++異常處理還不是很了解,看完本文后對您一定會大有幫助,下文除了學(xué)習(xí)C++異常處理的基本性質(zhì)外還對C++異常處理的新特性進(jìn)行全面研究。

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

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

此時(shí),處理程序要面對兩個(gè)難題:"如何知道異常是源于catch塊還是 程序的其他部分"和"如何跟蹤原來的異常"。我的解決方法是:在調(diào)用catch塊之前,把當(dāng)前異常保存在exception_storage對象中,并注 冊一個(gè)專用于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.         //主線程(第一個(gè)線程)不會收到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。如果是拋出了新異常,這個(gè)函數(shù)可以從 exception_storage對象中分離出前一個(gè)異常并銷毀它;如果是重新拋出原來的異常(可以通過ExceptionInformation數(shù)組 的前兩個(gè)元素知道是新異常還是舊異常,后一種情況下著兩個(gè)元素都是0,參見下面的代碼),就通過拷貝ExceptionInformation數(shù)組來繼續(xù) 傳播它。下面的代碼就是catch_block_protector()函數(shù)的實(shí)現(xiàn)。

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

每個(gè)線程都有自己單獨(dú)的 exception_storage,它在線程啟動時(shí)被創(chuàng)建,并在結(jié)束時(shí)被銷毀。Windows提供的線程局部存儲(thread local storage,TLS)可以滿足這個(gè)要求,它能讓每個(gè)線程通過一個(gè)全局鍵值來訪問為這個(gè)線程所私有的對象副本,這是通過TlsGetValue()和 TlsSetValue這兩個(gè)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++代碼編制
責(zé)任編輯:chenqingxiang 來源: CSDN
相關(guān)推薦

2010-01-27 15:29:45

C++異常處理

2021-03-25 07:44:39

C++異常處理開發(fā)技術(shù)

2010-01-26 17:27:58

C++C程序

2011-05-13 18:10:55

CC++

2010-01-27 16:39:48

C++編譯器

2011-08-19 15:05:29

異常處理

2023-11-13 17:01:26

C++編程

2011-03-31 09:30:07

CC++聲明

2010-01-25 18:05:40

C++語言

2010-01-14 09:55:30

C++標(biāo)準(zhǔn)庫

2019-10-15 14:53:05

物聯(lián)網(wǎng)技術(shù)設(shè)計(jì)

2010-01-22 18:33:17

C++編譯器

2024-01-22 13:05:00

C++編程異常處理

2010-01-11 10:01:25

C++的編程工具

2010-02-02 11:16:28

C++異常

2010-01-13 13:42:55

C++編譯器

2010-01-20 18:17:55

C++異常問題

2015-12-28 11:25:51

C++異常處理機(jī)制

2010-01-26 11:20:54

C++編輯器

2010-01-12 17:26:37

C++編譯器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號