当前位置:   article > 正文

C++ 异常处理总结

c++ 异常处理

一、C++ 异常处理

1.1 要点归纳

C++ 异常处理涉及到三个关键字:try、catch、throw。在c++程序中,任何需要检测异常的语句,都必须在try 语句块中执行,异常必须由紧跟着try语句后面的catch语句来捕获并处理,因此try与catch总是结合使用。

语法如下:

  1. throw [表达式];
  2. try
  3. {
  4. //try语句块
  5. }
  6. catch(类型 n 参数n)
  7. {
  8. //异常处理语句
  9. }

1.2 异常类型

C++ 的异常类型可以分为基本类型和聚合类型:

  • 基本类型:int、char、float
  • 聚合类型:指针、数组、字符串、结构体

C++ 语言本身以及标准库中的函数抛出的异常,都是 exception 类或其子类的异常。也就是说,抛出异常时,会创建一个 exception 类或其子类的对象。

  1. try{
  2. //可能抛出异常的语句
  3. }catch(exception &e){
  4. //处理异常的语句
  5. }

 之所以使用引用,是为了提高效率。如果不使用引用,就要经历一次对象拷贝(要调用拷贝构造函数)的过程。

定义新的异常:

通过继承和重载 exception 类来定义新的异常。

1.3 throw用作异常规范

(异常规范是 C++98 新增的一项功能,但是后来的 C++11 已经将它抛弃了,不再建议使用。)

throw 关键字除了可以用在函数体中抛出异常,还可以用在函数头和函数体之间,指明当前函数能够抛出的异常类型,这称为异常规范(Exception specification)

(1)声明了一个名为 func 的函数,它的返回值类型为 double,有一个 char 类型的参数,并且只能抛出 int 类型的异常。如果抛出其他类型的异常,try 将无法捕获,只能终止程序:

double func (char param) throw (int);

(2)函数可抛出多种类型的异常,用逗号隔开:

double func (char param) throw (int, char, exception);

 (3)如果函数不会抛出任何异常,那么( )中什么也不写:

double func (char param) throw ();

 如此,func() 函数就不能抛出任何类型的异常了,即使抛出了,try 也检测不到。

1.4 异常层次

  • 同一个try语句块可以对应多个catch语句块,catch语句块可以定义具体处理的异常类型,不同的类型的异常由不同的catch语句块处理;
  • try语句块可以抛出任何类型的异常,catch(...)用于处理所有类型的异常,任何异常都只能被捕获一次;
  • throw抛出的异常必须被catch处理,如果当前函数能够处理异常,继续执行;如果当前函数不能处理异常,函数停止执行并返回;
  • 未被处理的异常会顺着函数调用栈向上传递,直到被处理为止,否则程序将停止执行。
  1. try
  2. {
  3. throw 'c';
  4. }
  5. catch(char c)
  6. {
  7. cout << "catch(char c)" << endl;
  8. }
  9. catch(short c)
  10. {
  11. cout << "catch(short c)" << endl;
  12. }
  13. catch(double c)
  14. {
  15. cout << "catch(double c)" << endl;
  16. }
  17. catch(...)
  18. {
  19. cout << "catch(...)" << endl;
  20. }

 二、C++ 异常使用案例

2.1 普通类型异常

division() 在 try 块中被调用,它抛出的异常会被 try 检测到,进而被 catch 捕获。

  1. #include <iostream>
  2. using namespace std;
  3. double division(int a, int b)
  4. {
  5. if (b == 0)
  6. {
  7. throw "Division by zero condition!";
  8. }
  9. return (a / b);
  10. }
  11. int main() {
  12. int x = 50;
  13. int y = 0;
  14. double z = 0;
  15. try {
  16. z = division(x, y);
  17. cout << z << endl;
  18. }
  19. catch (const char* msg) {
  20. cerr << msg << endl;
  21. }
  22. return 0;
  23. }

抛出了一个类型为 const char* 的异常,因此,当捕获该异常时,我们必须在 catch 块中使用 const char*

若发生异常后,程序的执行流会沿着函数的调用链往前回退,直到遇见 try 才停止。 

2.2 自定义新的异常

  1. #include <iostream>
  2. using namespace std;
  3. struct MyException : public exception
  4. {
  5. const char* what() const throw ()
  6. {
  7. return "C++ Exception";
  8. }
  9. };
  10. int main() {
  11. try
  12. {
  13. throw MyException();
  14. }
  15. catch (MyException & e)
  16. {
  17. std::cout << e.what() << std::endl;
  18. }
  19. catch (std::exception & e)
  20. {
  21. //其他的错误
  22. }
  23. return 0;
  24. }

what() 是异常类提供的一个公共方法,它已被所有子异常类重载 。

2.3 标准异常

  1. #include <iostream>
  2. #include <stdexcept>
  3. using namespace std;
  4. int main(int argc, char *argv[])
  5. {
  6. int array[5] = {0};
  7. for(int i = 0; i < 5; i++)
  8. {
  9. array[i] = i;
  10. }
  11. try
  12. {
  13. for(int i = 0; i < 10; i++)
  14. {
  15. if(i >= 5)
  16. {
  17. throw out_of_range("out of range");
  18. }
  19. else
  20. {
  21. cout << array[i] <<endl;
  22. }
  23. }
  24. }
  25. catch(const out_of_range& e)
  26. {
  27. cout << e.what() << endl;
  28. }
  29. return 0;
  30. }

参考文献:

【1】C++ 异常处理: https://www.runoob.com/cplusplus/cpp-exceptions-handling.html

【2】C++异常处理入门,C++ try catch入门:http://c.biancheng.net/view/2330.html

【3】C++语言学习(十八)——异常处理: https://blog.51cto.com/9291927/2164586

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/714950
推荐阅读
相关标签
  

闽ICP备14008679号