C++中的异常处理

本文详细介绍了C++中的异常处理机制,包括调用abort()、返回错误码、异常机制、异常类型、异常规范、栈解退、异常与类和继承的关系,以及异常处理的注意事项。异常处理提供了一种在程序遇到错误时转移控制权的方式,允许更优雅的错误处理。在C++11中,异常规范被摒弃,推荐使用noexcept关键字。文章还强调了在设计程序时就考虑异常处理的重要性,以及异常与动态内存分配之间的潜在问题。
摘要由CSDN通过智能技术生成

1. 调用abort()

        Abort()函数的原型位于头文件cstdlib(或stdlib.h)中,其典型实现是向标准错误流(即cerr使用的错误流)发送消息abnormal program termination(程序异常终止),然后终止程序。它还返回一个随实现而异的值,告诉操作系统(如果程序是由另一个程序调用的,则告诉父进程),处理失败。abort()是否刷新文件缓冲区(用于存储读写到文件中的数据的内存区域)取决于实现。如果希望,也可以使用exit(),该函数刷新文件缓冲区,但不显示消息。程序清单1是一个使用abort()的小程序。

// 程序清单1 error1.cpp -- using the abort() function
#include <iostream>
#include <cstdlib>
double hmean(double a, double b);
int main()
{
    double x, y, z;
    
    std::cout << "Enter two numbers: ";
    while(std::cin >> x >> y)
    {
        z = hmean(x,y);
        std::cout << "Harmonic mean of " << x << " and " << y << " is " << z << std::endl;
        std::cout << "Enter next set of numbers < q to quit >: ";
    }
    std::cout << "Bye!\n";

    return 0;
}

double hmean(double a, double b)
{
    if(a == -b)
    {
        std::cout << "untenable arguments to hmean()\n";
        std::abort();
    }
    return 2.0 * a * b / (a + b);
}

        为了避免异常终止,程序应在调用hmean()函数之前检查x和y的值。然而,依靠程序员来执行这种检查是不安全的。

2. 返回错误码

        一种比异常终止更灵活的方法是,使用函数的返回值来指出问题。

        例如,ostream类的get(void)成员通常返回下一个输入字符的ASCII码,但到达文件尾时,将返回特殊值EOF。对hmean()来说,这种方法不管用。任何数值都是有效的返回值,因此不存在可用于指出问题的特殊值。在这种情况下,可使用指针参数或引用参数来将值返回给调用程序,并使用函数的返回值来指出成功还是失败。istream族重载>>运算符使用了这种技术的变体。通过告知调用程序是成功或失败,是的程序可以采取除异常终止程序之外的其他措施。仔细审视程序清单2提供的思想。

// 程序清单2 error2.cpp -- returning an error code
#include <iostream>
#include <cfloat>     // (or float.h) for DBL_MAX
bool hmean(double a, double b, double* ans);

int main()
{
    double x, y, z;
    
    std::cout << "Enter two numbers: ";
    while(std::cin >> x >> y)
    {
        if(hmeans(x, y, &z))
            std::cout << "Harmonic mean of " << x << " and " << y << " is " << z << std::endl;
        else
            std::cout << "One value should not be the negative " << "of the other - try again.\n";
        std::cout << "Enter next set of numbers < q to quit >: ";
    }
    std::cout << "Bye!\n";
    return 0;
}

bool hmean(double a, double b, double* ans)
{
    if(a == -b)
    {
        *ans = DBL_MAX;
        return false;
    }
    else
    {
        *ans = 2.0 * a * b / (a + b);
        return true;
    }
}

        另一个在某个地方存储返回条件的方法是使用一个全局变量。可能问题的函数可以在出现问题时将该全局变量设置为特定的值,而调用程序可以检查该变量。传统的C语言数学库使用的就是这种方法,它使用的全局变量名为errno。

3. 异常机制

        下面介绍如何使用异常机制来处理错误。C++异常是对程序运行过程中发生的异常情况(例如被0除)的一种响应。异常提供了将控制权从程序的一个部分传递到另一部分的途径。

对异常的处理有3个组成部分:

  • 引发异常
  • 使用处理程序捕获异常
  • 使用try块

        程序在出现问题时将引发异常。throw语句实际上是跳转,即命令程序跳到另一条语句。throw关键字表示引发异常,紧随其后的值(例如字符串或对象)指出了异常的特征。

        程序使用异常处理程序(exception handler)来捕获异常,异常处理程序位于要处理问题的程序中,catch关键字表示捕获异常。处理程序以关键字catch开头,随后是位于括号中的类型声明,它指出了异常处理程序要响应的异常类型;然后是一个用花括号括起的代码块,指出要采取的措施。catch关键字和异常类型用作标签,指出当异常被引发时,程序应跳到这个位置执行。异常处理程序也被称为catch块。

        try块标识其中特定的异常可能被激活的代码块,它后面跟一个或多个catch块。try块是由关键字try指示的,关键字try的后面是一个由花括号括起的代码块,标明需要注意这些代码引发的异常。        

        程序清单3演示了这3个元素如何协同工作。

// 程序清单3 -- using an exception
#include <iostream>
double hmean(double a, double b);

int main()
{
    double x, y, z;
    std::cout << "Enter two numbers: ";
    while(std::cin >> x >> y)
    {
        try{
            z = hmean(x, y);
        }
        catch(const char* s)
        {
            std::cout << s << std::endl;
            std::cout << "Enter a new pair of numbers: ";
            continue;
        }
        std::cout << "Harmonic mean of " << x << " and " << y << " is " << z << std::endl;
        std::cout << "Enter next set of numbers < q to quit >: ";
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值