2010-07-16 132 views
0

這就是我想要做的(這是一個真正的項目的簡化):如何正確實施最終條件?

int param; 
int result; 
void isolated(int p) { 
    param = p; 
    try { 
    // make calculations with "param" and place the 
    // result into "result" 
    process(); 
    } catch (...) { 
    throw "problems.."; 
    } 
} 

我不能改變的方式process()作品,因爲在這個項目不會創建這個功能,是第三方功能。它適用於全局變量paramresult,我們不能改變這一點。

isolated()從另一個參數process()回叫時出現問題。我想知道這種情況,但不知道該怎麼做,因爲finally在C++中不存在。我覺得我應該使用RAII技術,但在這種情況下無法正確理解如何去做。

這就是我如何與代碼重複使它:

int param; 
int result; 
void isolated(int p) { 
    static bool running; 
    if (running) { 
    throw "you can't call isolated() from itself!"; 
    } 
    running = true; 
    param = p; 
    try { 
    // make calculations with "param" and place the 
    // result into "result" 
    process(); 
    running = false; 
    } catch (...) { 
    running = false; // duplication! 
    throw "problems.."; 
    } 
} 
+0

我不明白。您想做什麼? (假設'finally'存在) – kennytm 2010-07-16 08:33:06

+0

問題是,我應該在* catch和'try'中放置*標誌,這顯然是代碼重複。我現在將延長這個問題 – yegor256 2010-07-16 08:38:53

+0

這是不清楚什麼是拋出異常。 – aggsol 2010-07-16 08:46:01

回答

1

我還是不太清楚如何finally這裏有關,但你可以嘗試Boost.ScopeExit,如果你想避免創建範圍的保護機構你自己。

例子:

#include <boost/scope_exit.hpp> 
#include <cstdio> 

int isolated(int p) { 
    static bool running = false; 
    if (running) { 
     printf("Throwing %d\n", p); 
     throw p; 
    } 
    printf("Starting %d\n", p); 
    running = true; 
    BOOST_SCOPE_EXIT((p)(&running)) { // <-- 
     printf("Stopping %d\n", p);  // <-- 
     running = false;     // <-- 
    } BOOST_SCOPE_EXIT_END    // <-- 

    // ... 
    if (p) 
     isolated(p*10); 
    // ... 
    printf("Returing %d\n", p); 

    return 4; 
} 

int main() { 
    printf(">> first\n"); 
    isolated(0); 
    printf(">> second\n"); 
    try { 
     isolated(1); 
     printf(">> third (should not be printed.)\n"); 
    } catch(int p) { 
     printf("Caught %d\n", p); 
    } 
    isolated(0); 
    printf(">> fourth\n"); 

    return 0; 
} 

結果:

 
>> first 
Starting 0 
Returing 0 
Stopping 0 
>> second 
Starting 1 
Throwing 10 
Stopping 1 
Caught 10 
Starting 0 
Returing 0 
Stopping 0 
>> fourth 
+0

非常感謝,這正是我期待的! – yegor256 2010-07-16 10:48:42

0

莫非這項工作?

int save = -10000000000; 
int param; 
int result; 

int isolated(int p) { 

    if (save != -10000000000) 
    { 
    // run the other condition 
    } 
    else 
    { 
    save = p; 
    param = p; 
    try { 
     // make calculations with "param" and place the 
     // result into "result" 
     process(); 
     return result; 
    } catch (...) { 
     return 0; 
    } 
    } 
} 
2

也許我沒說得對,但你爲什麼不用標誌?你想知道什麼時候從process()調用了isolated(),對嗎?

int isolated(int p) { 
    static int execDeep = 0; 
    execDeep++; 

    // your code here 

    execDeep--; 
} 

現在您可以檢查'execDeep'的值,> 1表示它在進程中被調用()時仍然被執行。

5

「finally」類似的情況是在C++中使用guard對象來處理的,它們在析構函數中做了最後的事情。這是恕我直言的更強大的方法,因爲你必須分析情況來確定才能創建一個可重用的對象。在這種情況下,我們需要製作流程租賃者,因爲參數和回報是以全局方式傳遞的。解決的方法是在進入時保存它們的值,並在退出時恢復它們:

template<class T> 
class restorer 
{ 
T &var; // this is the variable we want to save/restore 
T old_value; // the old value 
restorer(const restorer&); 
void operator=(const restorer&); 
public: 
restorer(T &v) : var(v), old_value(v) {} 
~restorer() { var=old_value; } 
}; 

int param; 
int result; 
int isolated(int p) { 
    restorer<int> rest_param(param); 
    restorer<int> rest_result(result); 

    param = p; 
    try { 
    // make calculations with "param" and place the 
    // result into "result" 
    process(); 
    return result; 
    } catch (...) { 
    return 0; 
    } 
} 
+0

+1以獲得良好的RAII。除非你對全局變量(你使用RAII進行處理)使用鎖定,否則它不會進行孤立的重入。 – 2010-07-16 09:07:38

+0

單線程可重入嗎?遞歸? – 2010-07-16 09:31:20

0

如果我理解正確的,你要自動設置運行標誌設置爲false,在函數結尾。如果這是要求,那麼你可以使用鏈接中提到的ScopeGuard