在堆栈中执行POP时下溢中的异常处理

时间:2014-12-31 04:41:01

标签: c++ algorithm stack

我想知道当顶部变量达到值 -1 时,如何应用异常处理(没有元素可以弹出) 。目前,我正在使用 cout 来向用户提供有关堆栈下溢并返回 0 的信息,这不是一个好习惯。总体上可以对此 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;

3 个答案:

答案 0 :(得分: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';
  }
}

编辑:正如下面提到的评论,您也可以从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

答案 1 :(得分:1)

RE

  

可以对此pop功能

进行总体改进

你可以

  • 使其void为其他项目类型提供更多例外安全 使用当前设计,如果复制弹出的项目失败,则无法恢复。
  • 删除内部输出。
  • assert未发生下溢,因此可以在测试中捕获。

因此,

void Mystack::pop()
{
    assert( top > 0 );
    --top;
}
哇,这是一个简化 - 现在也更加安全!

作为assert的替代方案,您可以抛出异常。这比原来好,但绝对不比assert好。它将正确性问题移动到运行时域中,以便处理并可能由每个调用者站点解决。

答案 2 :(得分: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;