外传篇2 函数的异常规格说明

1. 函数的异常规格说明

(1)C++提供语法用于声明函数所抛出的异常

(2)异常声明作为函数声明的修饰符,写在参数列表后面

//可能抛出任何异常
void func1();

//只能抛出的异常类型:char和int
void func2() throw(char, int);

//不抛出任何异常
void func3() throw();

//自定义结束函数
void my_terminate()

2. 异常规格说明的意义

(1)提示函数调用者必须做好异常处理的准备

(2)提示函数维护者不要抛出其它异常

(3)异常规格说明是函数接口的一部分

3. 异常规格之外的异常

(1)函数抛出的异常不在规格说明中全局unexpected()函数将被调用

(2)默认的unexpected()函数会调用全局的terminate()函数。

(3)可以自定义函数替换默认的unexpected()函数。(注意,不是所有的C++编译器都支持这个标准行为)

【编程实验】抛出的异常不在声明列表中,会发生什么?

#include <iostream>

using namespace std;

//抛出规格说明之外的异常
void func() throw(int)//指明该函数可能抛出一个int型的异常
{
    cout << "func()" << endl;

    throw ‘c‘; //抛出的却是字符型异常!
}

int main()
{
    try
    {
        func();
    }catch(int){
        cout << "catch(int)" << endl;
    }catch(char){
        cout << "catch(char)" << endl;
    }
    return 0;
}

/*输出结果:
1、g++编译及运行结果
func()
terminate called after throwing an instance of ‘char‘

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application‘s support team for more information.
2、VC++编译及运行结果(Vc可见没遵循标准规范,即调用unexpected)
func()
catch(char)
*/

4. unexpected()函数的替换

(1)自定义一个无返回值无参数的函数(可以再次抛出异常

  ①当异常符合触发函数(即哪个函数触发了异常)的异常规格说明时,恢复程序执行。

  ②否则,调用全局terminate()函数结束程序。

(2)调用set_unexpected()设置自定义的异常函数

  ①参数类型为void(*)()

  ②返回值为默认的unexpected()函数入口地址

【编程实验】自定义unexpected函数

#include <iostream>
#include <cstdlib>
#include <exception>

using namespace std;

void my_unexpected()
{
    cout << "void my_unexpected()" << endl;

    //exit(1);
    throw 1; //再次抛出的异常与触发函数(func)声明的中异常规格类型
             //一致,则程序恢复执行,所以会被catch(int)捕获
}

//抛出规格说明之外的异常
void func() throw(int)//指明该函数可能抛出一个int型的异常
{
    cout << "func()" << endl;

    throw ‘c‘; //抛出的却是字符型异常!
}

int main()
{
    set_unexpected(my_unexpected);

    try
    {
        func();
    }catch(int){
        cout << "catch(int)" << endl;
    }catch(char){
        cout << "catch(char)" << endl;
    }
    return 0;
}

/*输出结果:
1、g++和bcc编译及运行结果
func()
void my_unexpected()
catch(int)

2、VC++编译及运行结果(Vc可见没遵循标准C++规范,即调用unexpected)
func()
catch(char)
*/

5. 小结

(1)C++中的函数可以声明异常规格说明

(2)异常规格说明可以看作接口的一部分

(3)函数抛出的异常不在规格说明中unexpected()被调用

(4)unexpected()中能够再次抛出异常

时间: 2024-07-30 05:38:43

外传篇2 函数的异常规格说明的相关文章

外传二 函数的异常规格说明

如何判断一个函数是否会抛出异常,以及抛出哪些异常? 如果是第三方库函数我们看不到实现,只能看到声明,如何判断是否会抛出异常呢? 解决方案: 问题: 如果抛出的异常不在异常规格列表中,会发生什么? 示例: 1 #include <iostream> 2 3 using namespace std; 4 5 void func() throw(int) 6 { 7 cout << "func()"; 8 cout << endl; 9 10 throw

外传篇3 动态内存申请的结果

1. 必须知道的事实 (1)常见的动态内存分配代码 //C代码 int* p = (int*)malloc(10 * sizeof(int)); if(p != NULL){ //... } //C++代码 int* p = new int[10]; if(p != NULL){ //... } (2)必须知道的事实 ①malloc函数申请失败时,返回NULL值. ②new关键字申请失败时,则会根据编译器的不同,有的返回NULL值,而有的抛出std::bad_alloc异常. 2. new op

Vue学习笔记进阶篇——Render函数

本文为转载,原文:Vue学习笔记进阶篇--Render函数 基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接近编译器. <h1> <a name="hello-world" href="#hello-world"> Hello world! </a> </h1>

李洪强iOS开发Swift篇—07_函数

李洪强iOS开发Swift篇—07_函数 一.函数的定义 (1)函数的定义格式 1 func 函数名(形参列表) -> 返回值类型 { 2 // 函数体... 3 4 } (2)形参列表的格式 形参名1: 形参类型1, 形参名2: 形参类型2, … (3)举例:计算2个整数的和 1 func sum(num1: Int, num2: Int) -> Int { 2 return num1 + num2 3 } (4)没有返回值的函数 如果函数没有返回值,有3种写法 1 func 函数名(形参列

李洪强iOS开发Swift篇—08_函数(2)

李洪强iOS开发Swift篇—08_函数(2) 一.函数类型 函数类型也是数据类型的一种,它由形参类型和返回值类型组成,格式是 (形参类型列表) -> 返回值类型 1 func sum(num1: Int, num2: Int) -> Int { 2 return num1 + num2 3 } sum函数的函数类型是(Int, Int) -> Int 1 func printLine() 2 { 3 println("-----------") 4 } printL

计算机二级python 知识点篇(函数与代码复用)

计算机二级python 知识点篇(函数与代码复用) 全局变量 全局变量指在函数之外定义的变量, 在程序执行全过程有效. 全部变量在函数内部使用时, 需要提前使用保留字global声明, 语法形式如下: global <全局变量> >>>n = 2 #n是全局变量 >>>def multiply(x, y = 10): global n return x*y*n # 使用全局变量n >>>s = multiply(99, 2) >>

外传篇1 异常处理深度解析

1. main函数中抛异常 [编程实验]异常的最终处理 #include <iostream> using namespace std; class Test { public: Test(){ cout << "Test()" << endl; } ~Test(){ cout << "~Test()" << endl; } }; int main() { static Test t; throw 1; r

深入理解this机制系列第三篇——箭头函数

× 目录 [1]痛点 [2]解决 [3]基本用法[4]回调函数[5]注意事项 前面的话 this机制与函数调用有关,而作用域则与函数定义有关.有没有什么是可以将this机制和作用域联系起来的呢?本文将介绍ES6新增的内容——箭头函数 痛点 对于闭包的痛点在于,闭包的this默认绑定到window对象,但又常常需要访问嵌套函数的this,所以常常在嵌套函数中使用var that = this,然后在闭包中使用that替代this,使用作用域查找的方法来找到嵌套函数的this值 var a = 0;

Scala基础02:函数,异常

函数的默认参数 例: def decorate(str: String, left: String = “[”, right: String = “]”) = left + str + right 无参函数的调用可以不使用括号.但默认参数不代表没有参数.对于所有参数都是默认参数的函数,其调用必须使用括号. 例: def helloSpark(name:String = “Spark”){ println(name) } 调用该函数: helloSpark 错误 helloSpark() 正确 h