在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
异常类型的生命周期
1. throw 基本类型:int、float、char 这三种类型的抛出和函数的返回传值类似,为参数拷贝的值传递。 1 int test_1(int num) throw (int, double, char) 2 { 3 if (num == 0) 4 { 5 throw -1; 6 }else if (num == 1){ 7 throw 0.01; 8 }else{ 9 throw 'A'; 10 } 11 12 return 0; 13 } 14 15 int main() 16 { 17 int ret = 0; 18 try 19 { 20 ret = test_1(2); 21 } 22 catch (int error) { 23 printf("捕捉到 int 类型异常:%d", error); 24 }catch (double error) { 25 printf("捕捉到 double 类型异常:%f", error); 26 }catch (char error) { 27 printf("捕捉到 char 类型异常:%c", error); 28 } 29 30 return 0; 31 }
2 throw 字符串类型:string、char[num] 与普通变量区别不大,字符串抛出的是字符串的地址,如下边的代码: test() 传1 过去运行结果: 抛出 char * 字符串异常地址为:0097CDB8 test() 传2 过去运行结果: 抛出 string 字符串异常地址为:00CE5F18 抛出字符串与普通变量也没有多大区别,也是值传递,但传的是指针,而且修饰指针的 const 也要严格进行类型匹配。 1 int test(int num) throw (char *, string) 2 { 3 if(num == 1) 4 { 5 const char* error = "char* error = (char*)"; //修饰指针的 const 也要严格进行类型匹配。 6 printf("抛出 char * 字符串异常地址为:%p\n", error); 7 throw error; 8 } 9 else if (num == 2) 10 { 11 string *error = new string("string *error = new string"); 12 printf("抛出 string 字符串异常地址为:%p\n", error); 13 throw error; 14 } 15 16 return 0; 17 } 18 19 int main() 20 { 21 int ret = 0; 22 try 23 { 24 ret = test(1); 25 } 26 catch (const char *error) 27 { 28 printf("%s被捕获", error); 29 printf("异常地址为:%p\n", error); 30 } 31 catch (string *error) 32 { 33 printf("%s被捕获", error->c_str()); 34 printf("异常地址为:%p\n", error); 35 //别忘记释放内存 36 delete error; 37 } 38 39 return 0; 40 }
3 throw 类类型异常:首先要说明,throw 类类型的最佳方式是:抛出类的匿名对象,使用引用类型捕捉对象,这种方法效率最高,下边将会具体说明。 throw 类类型的生存周期分几种情况,生存周期的不同与编译器对于类的处理有关,用下方的代码举例: 1 #include <iostream> 2 #include <string> 3 4 class ErrorException 5 { 6 public: 7 ErrorException(); 8 ~ErrorException(); 9 ErrorException(const ErrorException& error); 10 11 private: 12 int ID = -1; 13 }; 14 15 ErrorException::ErrorException() 16 { 17 ID = 0; 18 printf("ErrorException 构造\n"); 19 } 20 21 ErrorException ::~ErrorException() 22 { 23 printf("ErrorException ~析构 (ID:%d)\n", ID); 24 } 25 26 ErrorException::ErrorException(const ErrorException& error) 27 { 28 ID = 1; 29 printf("ErrorException 拷贝构造函数\n"); 30 } 31 32 int test(int num) throw (ErrorException) 33 { 34 if (num == 1) 35 { 36 throw ErrorException(); //这里抛出的是匿名对象 37 } 38 39 return 0; 40 } 41 42 int main() 43 { 44 int ret = 0; 45 try 46 { 47 ret = test(1); 48 } 49 catch (ErrorException &error) 50 { 51 printf("捕捉到异常!ErrorException 类型\n"); 52 } 53 catch (...) 54 { 55 printf("没有捕捉到异常类型\n"); 56 } 57 58 return 0; 59 } =================================================================================== ErrorException 构造 说明:调用了两次析构函数,一次是在 36行创建了匿名对象抛出,一次是在49行,因为使用了形参值传递,会进行两个对象的创建。 从ID 的变化可以看出,先析构拷贝构造函数,后析构构造函数。
ErrorException 构造 说明:使用引用的话,将会少创建一个对象,是36行的“临时匿名对象”的地址进行抛出,捕捉时直接捕捉引用,不用再次创建,这种效率最高。
1 /* . . . 省略 . . . */ 2 int test(int num) throw (ErrorException) 3 { 4 if (num == 1) 5 { 6 ErrorException error; //进行对象创建 7 throw error; //进行对象抛出 8 } 9 10 /* . . . 省略 . . . */ 11 try 12 { 13 ret = test(1); 14 } 15 catch (ErrorException error) //使用形参接收 16 { 17 printf("捕捉到异常!ErrorException 类型\n"); 18 } 运行结果: ErrorException 构造 说明: ErrorException 构造 ------------> 36 行创建对象
=================================================================================== 如果使用指针进行异常抛出,大同小异,用上边的代码举例,要注意的就是内存的释放,如下代码: 1 /* . . . 省略 . . . */ 2 int test(int num) throw (ErrorException) 3 { 4 if (num == 1) 5 { 6 throw new ErrorException(); //动态内存分配 7 } 8 9 /* . . . 省略 . . . */ 10 catch (ErrorException *error) 11 { 12 printf("捕捉到异常!ErrorException 类型\n"); 13 delete error; //注意释放内存 14 } 运行结果: ErrorException 构造 ===================================================================================
1. 异常处理的三个关键字2. 异常处理的基本语法3.异常处理接口声明4.异常类型的生命周期4.1 throw 基本类型:4.2 throw 字符串类型:4.3 throw 类类型异常:5.异常和继承6.异常处理的基本思想7.标准库里的异常类 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论