jackyung
一般會員
發表:22 回覆:46 積分:13 註冊:2004-01-24
發送簡訊給我
|
在 BCB 中可用 try __finally 來處理例外,
請問在標準 C++ 中要怎麼做? 如下:
pLockXY->Acquire(); // lock out other threads
try
{
Y = sin(X);
}
__finally
{
pLockXY->Release();
} 是不是得這樣做: pLockXY->Acquire(); // lock out other threads
try
{
Y = sin(X);
}
catch(...)
{
pLockXY->Release(); // 得重複寫一次? 天啊
throw;
}
pLockXY->Release();
|
pwipwi
版主
發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
jackyung你好:
使用local物件的destructor可以達到這個功用。不過也是有點麻煩。但至少比catch(...)來的有保險。記得前不多時站上有討論文章提到catch(...)無法抓到所有類型的exception的問題。這時如果用local物件一定會解構的特性,就可以安全的做出finally的功用。
|
jackyung
一般會員
發表:22 回覆:46 積分:13 註冊:2004-01-24
發送簡訊給我
|
可是有些不是要做解構處理,比如 TCriticalSection 的 Release 動作,
還是有什麼辦法可以在進入和離開函數時,可以做一些前置和後置處理,
我的想法是做一個 class,用它做成 local 物件,利用它的 Constructor 和 Destructor 來做前置和後置處理,可是要處理的東西都不同,有辦法做一個
通用的 class 嗎?還是已有什麼現成的東西可用?
|
pwipwi
版主
發表:68 回覆:629 積分:349 註冊:2004-04-08
發送簡訊給我
|
用template class可以做到這個通用的目的。製作一個local的class由template產生,最後他的destructor中呼叫release即可。 國外就有人覺得Windows的Handle種類太多,每個Release的function又不太相同,於是寫了一個統一介面的template class讓他自已釋放。try和finally都不用寫,發生exception時也可以正常運作。 發表人 - pwipwi 於 2005/03/23 23:58:16
|
jackyung
一般會員
發表:22 回覆:46 積分:13 註冊:2004-01-24
發送簡訊給我
|
找到了一個範例 "为什么C 不提供“finally”的构造" http://www.trainlinux.com/p/2003-05-24/4091.html 覺得要做一個通用的 class 蠻難的,就物件而言不一定提供 Release(),
而且 finally 要做的不只是處理其他物件,可能還要處理函數本身一些殘局,
C 沒提供 finally 還真奇怪
|
jackyung
一般會員
發表:22 回覆:46 積分:13 註冊:2004-01-24
發送簡訊給我
|
我想到要怎麼做了,哈哈,蠻爽的,
這樣就可省掉對 finally 的部分依賴
#include // 通用性的物件回收類別,
// 須作為 local 物件使用
template
class SuperHandle
{
T *Obj; // 包裝要處理的物件 // 登記處理的物件提供的成員函數
// PreFunc 會在建構時呼叫
// PostFunc 會在解構時呼叫
void (__fastcall T::*PreFunc)(void); // 這個 __fastcall 可以想辦法去除
void (__fastcall T::*PostFunc)(void);
public:
// Constructor
SuperHandle(T *obj,void (__fastcall T::*preFunc)(void),void (__fastcall T::*postFunc)(void))
{
Obj = obj;
PreFunc = preFunc;
PostFunc = postFunc;
(Obj->*PreFunc)();
} // Destructor
~SuperHandle(void)
{
(Obj->*PostFunc)();
} }; // 測試
class Test
{
int data;
protected:
TCriticalSection *PLock; // 關鍵區域物件,用來測試通用性的物件回收類別
public:
Test(void)
{
data = 100;
PLock = new TCriticalSection;
} virtual ~Test(void)
{
delete PLock;
} void Set(int v)
{
// 這樣使用通用性的物件回收類別
SuperHandle AutoDes
(PLock,
&TCriticalSection::Enter,
&TCriticalSection::Leave); int temp = data;
temp = v;
temp /= (temp % v);
data = temp;
} int Get(void)
{
// 這樣使用通用性的物件回收類別
SuperHandle AutoDes
(PLock,
&TCriticalSection::Enter,
&TCriticalSection::Leave); data /= ((data 5) % 7);
return data;
}
}; void __fastcall TForm1::Button2Click(TObject *Sender)
{
Test* p = new Test; p->Set(500); p->Set(p->Get()); }
|