2014-12-31 77 views
2

做POP我想知道如何當頂部變量達到一個值-1申請異常處理(無元素留下來的POP)。目前,我正在使用cout來向用戶提供關於堆棧下溢和返回,這不是一個好的做法。對於這個pop函數,以及如何在堆棧達到下溢狀態時通知用戶並處理異常,總體上可以做出什麼改進。異常處理下溢,而在堆棧

int Mystack::pop() 
{ 
    if (isEmpty()) 
    { 
     std::cout << "Stack Underflow" << std::endl; 
    } 
    else 
    { 
     std::cout << "The popped element is" << A[top]; 
     return A[top--]; 
    } 
    return 0; 
} 

主段:

case 4: 
      std::cout << "POP the element" << std::endl; 
      s1.pop(); 
      break; 

回答

5

可以拋出out_of_range例外:

#include <stdexcept> 
int Mystack::pop() 
{ 
    if (isEmpty()) 
     throw std::out_of_range("Stack Underflow"); 
    std::cout << "The popped element is" << A[top]; 
    return A[top--]; 
} 

在客戶端:

void foo() 
{ 
    Mystack ms; 
    //... 
    try 
    { 
    ms.pop(); 
    } 
    catch (const std::out_of_range& oor) 
    { 
    std::cerr << "Out of Range error: " << oor.what() << '\n'; 
    } 
} 

編輯:正如下面的評論提到,你c一個也從std::exception派生自己的例外。下面是一個簡單的例子:

#include <stdexcept> 
struct myStackException : public std::exception 
{ 
    const char *what() const noexcept { return "Stack Overflow"; } 
}; 

int Mystack::pop() 
{ 
    if (isEmpty()) 
     throw myStackException(); 
    std::cout << "The popped element is" << A[top]; 
    return A[top--]; 
} 

直播(虛擬)例如:http://ideone.com/ZyqiQ0

+0

['std :: out_of_range'](http://en.cppreference.com/w/cpp/error/out_of_range)在''頭部。 – ikh

+0

謝謝,糾正了這個帖子。關於'out_of_range'的 – PaulMcKenzie

+0

,其優點是它聽起來符合。缺點包括(1)[抱歉,刪除],和(2)它將通過僅捕獲'runtime_error'的代碼飛行。除了這些考慮之外,我認爲應該提及的是,這種'pop'的設計對於其他堆棧項類型(一般來說)並不是特別安全的。 –

1

重新

可以到這個pop功能

做出什麼改進整體你可以

  • 使它void使其更例外安全爲其他項目類型。
    使用目前的設計,如果彈出項目的複製失敗,則無法恢復。
  • 刪除內部輸出。
  • assert表示下溢不發生,所以這可以在測試中被捕獲。

因此,

void Mystack::pop() 
{ 
    assert(top > 0); 
    --top; 
} 

哇,簡化–現在越來越異常安全的呢!

作爲assert的替代方案,您可以引發異常。這比原來的要好,但絕對不比assert好。它將正確性問題轉移到運行時域中,並由每個呼叫者站點處理並解決。

1

使用C++異常的好處是可以將錯誤處理代碼從用戶代碼中分離出來,從而減輕代碼在C程序中常見的錯誤處理代碼的浪費。拋出一個異常,還提供了一個解決方案,在錯誤的情況下返回值無效

if(s1.pop() == 0){ 
    // is this an error or not? 
} 

例外可以被添加到您的代碼像這樣,通過在

#include <stdexcept> 

頭採取了一般例外優勢文件。

int Mystack::pop() 
{ 
    if (isEmpty()) 
    { 
     throw std::range_error("nothing to pop"); 
    } 
    std::cout << "The popped element is" << A[top]; 
    return A[top--]; 
} 

然後你一個try/catch塊添加到相應的代碼,也許

case 4: 
     std::cout << "POP the element" << std::endl; 
     try{ 
      s1.pop(); 
     } 
     catch(const std::range_error& e) 
     { 
      std::cerr << "unable to pop!\n"; 
      // error handling code 
     } 
     break; 

另一種解決方案,特別是在適當的時候錯誤是沒有例外的,如文件I/O是更具侵入到用戶代碼,但提供了更好的解決方案比返回任意值

int Mystack::pop(int& value) 
{ 
    if(isEmpty()) 
    { 
     return 1; 
    } 
    std::cout << "The popped element is" << A[top]; 
    value = A[top--]; 
    return 0 
} 

然後你的代碼變得

case 4: 
    std::cout << "POP the element" << std::endl; 
    { 
     int value; 
     if(s1.pop(value) == 1){ 
      // error code 
     } 
    } 
     break; 
相關問題