2011-03-17 22 views
5

一切我曾經被告知的是,去的是邪惡的遠離他們,但我認爲他們可以幫助我在這裏(?)。我想給用戶提供一個選項,以重新啓動應用程序時,一個異常被捕獲時遇到一點麻煩纏繞我身邊做什麼頭......是不是還好用「去」從catch語句

我的申請將被其他進程進行監測,但有有一些例外,我希望用戶能夠決定如何執行操作,而無需將控制權返回給調用進程。

是這樣的「可以接受」?還有其他建議嗎?

非常感謝!

int main(){ 

    initialize: 
     try{ 
     //do things 
     } 
     catch(...) 
     { 
      cout<<"Would you like to try initializing again?"<<endl; 

      //if yes 
      goto initialize; 

      //if not 
      abort(); //or something... 
     } 

return 0; 
} 
+4

這種對goto的狂怒仇恨是奇怪的。我猜這是同樣的人在每篇關於優化的文章中尖叫過早的優化。 – Inverse 2011-03-17 17:39:45

+1

@反過來:95%的關於優化的帖子是不成熟的(即在「測量,優化,測量」中的「測量」之前)並不是我們的錯。但是,這不是一個*位* OT? ;-) – DevSolar 2011-03-17 18:07:59

回答

4

是的,從技術上說它沒關係,但通常「goto認爲有害」的考慮適用。

+2

goto永遠不會好 - 避免它像瘟疫一樣。它會咬你,當你有一個錯誤後。永遠不要考慮它。 – Paul 2011-03-17 15:39:35

+4

@Paul:你有比較有多少人被瘟疫殺死,有多少人使用'goto'死亡? – sharptooth 2011-03-17 15:41:17

+4

'goto'確定。它是最簡單的流量控制機制,並且找到跳躍目標比其他幾乎都簡單。如果它避免了重複,那麼它就沒有問題;在C++中,使用'goto'綁定自己的節點幾乎是不可能的,因爲你實際上無法走到任何足夠遠的地方,以至於它可能會導致一個你還沒有的問題。 – 2011-03-17 15:44:32

7

爲什麼不喜歡這個?

while(true){ 
    //Do stuff 
    if(exit){ 
    break; 
    } 
} 

continue = true; 
do{ 
    //Do stuff 
    if(exit){ 
    continue = false; 
    } 
}while(continue); 
+0

+1,這是方式,沒有goto需要。 – murrekatt 2011-03-17 15:36:51

+0

如果需要,你將如何回到while循環?另外,對try/catch有什麼影響?我正計劃捕捉許多不同類型的異常,並且需要讓用戶選擇做什麼...... – JonnyK 2011-03-17 15:41:27

+2

@Jon,如果您需要跳入和跳出循環,那麼您必須將其分開函數,然後在需要時調用該函數。 – 2011-03-17 15:46:32

5

你可以嘗試:

int main() 
{ 
    while(true) 
    { 
      try 
      { 
       program(); 
      } 
      catch(std::exception& e) 
      { 
       std::cout << "Start again?" << std::endl; 
       //Check ... 
       if(!go_on) 
        break; 
      } 
    } 
    return 0; 
} 
1

的異常處理的正常方法是在那裏你可以做一些事情的地方。很明顯,你正試圖處理它們的地方是不對的,因爲你必須使用goto。

所以,這樣的事情:

void mainLoop() // get user settings, process, etc 
{ 
    try 
    { 
    // 1) get user settings 
    // 2) process data 
    // 3) inform of the result 
    } 
    catch(const exception_type & e) 
    { 
    // inform of the error 
    }  
} 

int main() 
{ 
    try 
    { 
    while(true) 
     mainLoop(); 
    } 
    catch(...) 
    { 
    std::cout<<"an unknown exception caught... aborting() " << std::endl; 
    } 
} 
+0

但是如果你重新啓動mainLoop()它會在try塊之外,不是嗎? – JonnyK 2011-03-17 15:45:53

+0

@Jon對,我修正了這個例子 – 2011-03-17 15:57:31

1

原帖是(我相信) 「無節制使用goto認爲是有害的」。 Gotos可以是有用的,但必須以受控的方式使用。有一種編程技術可以根據程序或數據的狀態創建可重入的子程序,這些程序或數據肯定要求直接跳轉。儘管這種技術可能被認爲是過時的,但我知道它仍然被使用,但被更現代的語言和編譯器功能所隱藏。控制的要點是,你必須停下來問問自己,不僅僅是「有沒有更有條理的做同樣的事情」 - @Justin--而且「在什麼樣的條件下我會用goto?」如果沒有這個更廣泛的答案,使用它可能不是一個充分的條件。

+3

問題在於我們中的一些人已經編程了幾十年,甚至沒有發現這些「特定條件」,甚至一次。他們一定是非常罕見的! – 2011-03-17 16:24:32

+1

使用這種方法的方法實質上是傑克遜結構化編程。該技術是設計獨立的通信程序,然後「倒置」其中一個程序,成爲可重入,有狀態的一系列子程序。這隻能通過用無循環代碼編寫被調用的程序來完成 - 並且派生無循環代碼的方式是用gotos代替循環結構。這是由(至少)C,Pascal和Cobol的預處理器自動完成的。這種方法在英國和斯堪的納維亞廣泛使用,在許多私人,政府和軍事項目中。 – 2011-03-17 17:01:23

+0

好的,使用機器生成的代碼與gotos類似於編譯器生成jmp的break和continue。我自己從來沒有寫過任何歌曲,甚至沒有接近過。 – 2011-03-17 17:20:08

6

A goto可以總是可以避免,給予更乾淨的代碼。

順便說一句,同樣也適用於一個switchbreak秒。 continue關鍵字的可譴責性稍低,因爲至少它會尊重封閉循環的條件。在這裏你可以最有效地處理條件 -

它趕在正確的地方例外是很重要的。

如果條件真可謂是不方便(如在我的情況「再試一次嗎?」),認爲否定它(「失敗?」)對淨化器結構。

// Tries until successful, or user interaction demands failure. 
bool initialize() { 
    for (;;) { 
     try { 
      // init code 
      return true; 
     } 
     catch (...) { 
      cout << "Init Failed. Fail Program?" << endl; 
      if (yes) { 
       return false; 
      } 
     } 
    } 
} 

int main() { 
    if (! initialize()) { 
     return EXIT_FAILURE; 
    } 
    // rest of program 
    return EXIT_SUCCESS; 
} 

注:此不使用gotobreak,並且它不遞歸(尤其是從catch塊內不是)。

+3

終於有人得到它+1 – Paul 2011-03-17 15:50:35

+1

早期的回報只是一個變相的轉變?開玩笑! – 2011-03-17 16:20:43

+0

@波佩爾森:試着畫出我早期迴歸的納西 - 施奈德曼圖。我打扮成gotos的'break'解決方案。您將看到不同之處:早期回報離開整個街區,而休息區則嘗試跳轉到街區的其他位置。沒有開玩笑。 ;-) – DevSolar 2011-03-17 16:22:15

相關問題