【C/C++】C++中的异常

异常

程序在实际运行时,总会有一些因素会导致程序不能正常运行。异常就是提前给出处理这些不正常因素的解决方案的机制。主要是为了程序的稳定性。

C++中的异常

关键字

在C++中主要提供了3个关键字实现异常处理。分别是:

  • try:捕捉异常

    try块中的代码将会进行异常捕捉。

  • catch:处理异常

    在catch块中进行对应异常的处理。可以有多个catch块处理不同的异常。异常类可以是任何类型,比如int、long、char*、自定义类。

  • throw:抛出异常

    抛出异常后,throw下面的语句将不会被执行。此时执行退栈操作。

Java中的异常机制就是使用C++的异常实现的。

异常处理中的退栈和对象析构

在函数调用时,函数中定义的自动变量将在堆栈中存放。结束函数调用时,这些自动变量就会从堆栈中弹出,不再占用堆栈的空间,这个过程也被称为”退栈”。退栈时会调用对象的析构函数并释放对象。

异常使用示例

#include <iostream>

void main(){

    try
    {

        // 在try块中的代码抛出的异常将会被捕捉

        throw "异常了";  // throw可以抛出任何类型的异常,比如char*、int、自定义类

        // throw下面的代码将不会被执行,此时执行退栈操作。

        std::cout << "--------------------" << std::endl;

        throw 505;
    }
    catch (const char* str) //根据类型catch不同的异常,并在catch块中对该异常作处理
    {
        std::cout << "error msg : " << str << std::endl;
    }
    catch (int i)
    {
        std::cout << "error code : "<< i << std::endl;
    }
}

自定义异常类

子类异常要放在父类异常的前面,不然子类异常将永远不会被catch到。但可以使用虚函数实现同一个接口处理不同的异常。

// 异常类
class Exception{
protected:
    std::string _msg;
public:
    Exception(){
    }
    Exception(std::string &str){
        _msg = str;
    }
    virtual void print(){
        std::cout << _msg.c_str() << std::endl;
    }
};

// 数组下标访问越界异常
class ArrayIndexOutOfBoundsException:public Exception{
protected:
    int _errorIdx;
public:
    ArrayIndexOutOfBoundsException(int idx){
        _errorIdx = idx;
    }
    void print(){
        std::cout << "ArrayIndexOutOfBoundsException : 尝试访问下标" << _errorIdx << "时发生错误。" << std::endl;
    }
};

// 数组
template<class T>
class Array{
private:
    int _size = 0;
    T *arr = nullptr;
public:

    Array(int size){
        arr = new T[size];
        _size = size;
    }

    ~Array(){
        if (arr)
        {
            delete[] arr;
            arr = nullptr;
        }
    }

    T& operator[](int idx){
        // 检查下标
        if (idx < 0 || idx >= _size)
        {
            throw ArrayIndexOutOfBoundsException(idx); //数组下标访问越界
        }
        return arr[idx];
    }
};

void main(){

    int size = 5;

    try{
        Array<int> arr(size);

        for (int i = 0; i < size; ++i)
            arr[i] = i + 1;

        // 异常
        arr[-1] = 0;

        for (int i = 0; i < size; ++i)
        {
            std::cout << "arr[" << i << "] = " << arr[i] << std::endl;
        }
    }
    // 子类异常要放在父类异常之前
    catch (ArrayIndexOutOfBoundsException &e){
        e.print();
    }
    catch (Exception &e){
        e.print();
    }
}
时间: 2024-10-10 00:26:48

【C/C++】C++中的异常的相关文章

Laravel 5.4 中的异常处理器和HTTP异常处理实例教程

错误和异常是处理程序开发中不可回避的议题,在本地开发中我们往往希望能捕获程序抛出的异常并将其显示打印出来,以便直观的知道程序在哪里出了问题并予以解决,而在线上环境我们不希望将程序错误或异常显示在浏览器中(出于安全考虑),这个时候我们仍然要捕获异常,只不过不是显示到浏览器中,而是记录到日志中,方便日后排查问题. 百牛信息技术bainiu.ltd整理发布于博客园 Laravel当然支持PHP原生的错误和异常处理,但是在此基础上进行了一些封装处理,从而更方便在不同开发环境切换以及对错误和异常的处理.

[C++11 并发编程] 16 在期望中保存异常

如果在异步线程中发生了异常,等待期望的线程如何才能知道并且正确的处理异常呢? 假设有如下所示的一个求平方根的函数: double square_root(double x) { if(x<0) { throw std::out_of_range("x<0"); } return sqrt(x); } 通常,如果在当前线程上下文中调用square_root(),方法如下: double y=square_root(-1); 在异步线程中调用square_root(),方法如下

Java中的异常和处理详解

原文出处:代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. Java提供了更加优秀的解决办法:异常处理机制. 异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰. Java中的异常可以是函数中的语句执行时引发的,也可以是程序员通过throw 语句手

编写高质量代码改善C#程序的157个建议——建议66:正确捕获多线程中的异常

建议66:正确捕获多线程中的异常 多线程的异常处理需要采用特殊的方式.一下这种方式会存在问题: try { Thread t = new Thread((ThreadStart)delegate { throw new Exception("多线程异常"); }); t.Start(); } catch (Exception error) { MessageBox.Show(error.Message + Environment.NewLine + error.StackTrace);

WCF中的异常

   一.考虑到安全因素,为了避免将服务端的异常发送给客户端.默认情况下,服务端出现异常会对异常屏蔽处理后,再发送到客户端.所以客户端捕捉到的异常都是同一个FaultException异常. 例如在服务端直接产生一个空引用异常,客户端捕获到的是上述异常. 服务端: class Program { static void Main(string[] args) { ServiceHost host = new ServiceHost(typeof(SayHello)); host.AddServi

JAVA中的异常(异常处理流程、异常处理的缺陷)

异常处理流程 1)首先由try{...}catch(Exception e){ System.out.println(e); e.printStackTrace(); }finally{...}结构 2)当JVM遇到异常时,会产生一个Exception对象 或 继承自Exception的子类的对象. 3)将异常对象向上层(调用它的代码块)抛出,知道碰到一个catch块(作相应处理) 或 一直抛到了最外层(导致程序异常终止).(并停止异常之后的代码的执行,但是finally块中的代码还会执行!换句

java中关于异常的处理

初学java的时候,当我们碰到异常时,一般会把异常直接throws抛出去,或则在catch的时候,简单的写一句打印异常信息,但是在实际开发中,是不能这么做的.如果我们将底层的某一个异常简单的print出去,那么这个异常的捕获是没有起到任何作用,反而给编译器一个"异常已处理"的假象,导致有异常的程序会继续往下执行,这是不允许的:如果我们直接将异常抛出去,抛给上一层,也是徒劳的,反而给上一层带来麻烦. 为了避免这样的情况发生,我们一般会将异常进行转换,将编译时异常转变成运行时异常,再thr

【PLSQL】Oracle中的异常

一.摘要 在PLSQL程序开发过程中,很重要的部分就是对程序异常的监控和处理,包括如何触发异常,何时进行处理,如何进行处理,是否将程式中的所有异常集中在一起,通过公共异常处理的procedure或function,如果没有完善的程式处理机制,很难说该程式是一只健壮的程式,当程式遇到很多类型或者量很多资料时,系统若没有异常处理必然会导致程式的出错 当预判到了某些异常,需要对预判到的异常进行合适相应的处理,是否抛出异常还是忽略还是其他 当然程式没有预判到或者是一些未知的异常遇到,所以异常处理模块也要

C++中的“error:LNK2005 已经在*.obj中定义”异常问题

C++中的“error:LNK2005 已经在*.obj中定义”异常问题 异常现象如下:

.NET中的异常和异常处理

.NET中的异常(Exception) .net中的中异常的父类是Exception,大多数异常一般继承自Exception. 可以通过编写一个继承自Exception的类的方式,自定义异常类! 异常处理机制 Try { 可能发生异常的代码 后续代码 } Try以外的代码 catch(Exception e) { } finally { } 上述代码描述如下 1.谁能执行 在异常处理中,一旦try里面有了问题,程序会放弃异常的后续代码直接跳到catch中. 执行完了catch中的代码,继续执行T