当前课程知识点:C++语言程序设计进阶 >  第十二章 异常处理 >  异常处理中的构造与析构 >  异常处理中的构造与析构

返回《C++语言程序设计进阶》慕课在线视频课程列表

异常处理中的构造与析构在线视频

异常处理中的构造与析构

异常处理中的构造与析构

自动的析构

例12-2 带析构语义的类的C++异常处理

//12_2.cpp
#include <iostream>
#include <string>
using namespace std;
class MyException {
public:
    MyException(const string &message) : message(message) {}
    ~MyException() {}
    const string &getMessage() const { return message; }
private:
    string message;
};

class Demo {
public:
    Demo() { cout << "Constructor of Demo" << endl; }
    ~Demo() { cout << "Destructor of Demo" << endl; }
};
void func() throw (MyException) {
    Demo d;
    cout << "Throw MyException in func()" << endl;
    throw MyException("exception thrown by func()");
}

int main() {
    cout << "In main function" << endl;
    try {
        func();
    } catch (MyException& e) {
        cout << "Caught an exception: " << e.getMessage() << endl;
    } 
    cout << "Resume the execution of main()" << endl;
    return 0;
}
运行结果:
In main function
Constructor of Demo
Throw MyException in func()
Destructor of Demo
Caught an exception: exception thrown by func()
Resume the execution of main()



下一节:标准程序库异常处理

返回《C++语言程序设计进阶》慕课在线视频列表

异常处理中的构造与析构课程教案、知识点、字幕

大家好

欢迎继续学习C++语言程序设计

这一节我们来了解

异常处理中的构造与析构

我们知道如果一段代码

它有可能发生异常

我们就应该把它放在try块里面

这样的话

当异常抛出的时候

这个异常才能够被try catch

这种机制

去捕获 去处理

那么就有一个问题了

大家肯定已经有这个疑问了

如果我在try块中

还没有执行完

执行到中间某一句的时候

发生异常了

抛出异常了

那try块从异常发生点开始

往后的部分还执行吗

它就不执行了

在try块中执行到任何一个地方

一旦发生了异常

后面的就不会再继续执行了

异常一抛出

可能被catch捕获

然后就去处理异常去了

那么如果说

在try块中

我们构造了一些对象

还没来得及析构

那么就遇到了异常

就抛出了异常

那这个程序不完整啊

构造的对象

它有机会被析构吗

资源会不会因此而泄漏呢

这个问题其实在C++中

它已经有很严密的机制了

大家不用担心这一点

接下来我们来看

具体的在异常过程中的构造

和析构配合的问题

在try块中

发生了异常以后

后面的内容就不会再执行了

直接抛出这个异常

离开这个try块

紧接着try块后面

就会有catch子句

catch如果匹配到了

抛出的异常类型

就要对异常参数进行初始化

这个很类似于

我们调用子函数的时候

初始化形参

那么这个时候catch

会用它捕获到的这个异常

去初始化它的异常参数

然后呢

还会从对应的try块开始

在try块中如果遇到了异常

从异常点开始往后的代码

就不会执行了

然后它抛出异常

抛出的异常呢

如果被跟在它后面的catch子句

捕获到了

那么catch子句

就会用它捕获到的这个异常对象

去初始化异常参数

这个初始化

很像我们调用子函数的时候

用实参初始化形参的那种初始化

初始化完异常参数以后呢

还会将从对应的try块开始

到异常被抛掷处之间

构造了

而且还没有被析构的这些对象

进行自动地析构

现在大家可以放心了 对吧

如果进到try块中

有对象被构造了

还没来得及析构

就终止try块里面内容的执行

就抛出异常

然后流程进到catch块

那么那些已经构造

还没有被析构的对象

会在第一时间自动被析构

这样就确保不会造成资源的泄漏

那么这个cacth块里面的内容

处理完了以后

会从最后一个catch处理之后

开始恢复执行

接下来呢

我们来看一个例题

看看在这个例题中是怎么样

对try块中构造了

但是还没有析构的这些对象

进行处理的

这个处理过程

其实它是自动的

但是我们可以观察得到

这个处理过程

通过这个例子我们来观察一下

在异常处理的时候

它的析构问题是怎么解决的

也就是说

当发生异常

抛出异常以后

那try块里面的其他部分

就要终止执行了

这个时候已经构造了

但是还没有析构的对象

能不能安全地析构呢

我们来通过这个例子观察一下

首先

看这儿我们定义了一个

MyException类

这是我们自定义的一个异常类

接下来在程序中呢

我们将要抛出

这个类型的一个对象

作为异常对象

然后我们再来看

这儿定义了一个Demo类

也就是在程序中

我们将构造Demo类的对象

然后在发生异常的时候呢

我们观察已经构造过的对象

是否正确地析构了

现在我们来看

在主函数中呢

我们在try块中调用一个函数func

那么这个func函数呢

它是有可能要抛出异常的

我们看这个函数定义在这儿

它声明了要有可能抛出

MyException类型的异常

所以我们就将这个函数调用

放在try块里面

紧接着后面用catch子句

去捕获MyException的异常

然后调用它的getMessage函数

去输出异常相关的信息

再看在这个函数里面

我们定义了一个

Demo类型的对象d

然后没有

其实没有做什么特别的计算

就是模拟在这里面

如果发生了一个什么情况的话呢

我们会抛出异常

所以在这里面输出一行提示信息

然后紧接着就抛出一个

MyException异常

对象d还没有被析构呢

如果它正常执行到

这个函数结束

这个局部对象是会自动析构的

但是现在没有正常执行到

函数结束的地方

在中途就因为抛出异常

终止了这个函数的执行

这个时候呢

程序流程就回到它的调用者了

回到主函数中了

这个func函数它抛出了异常

实际上在这个时候

这个异常处理机制

就保证这个异常抛出以后

在进入try块以后

抛出异常之前

构造的对象

是肯定能够由异常处理机制

给它自动析构的

所以在这个过程中应该

对象d应该被析构

然后才进入这个catch块里面

去处理这个异常

最后输出一行信息

结束主函数

我们看一下

输出结果是不是这样的

的确是这样的

首先我们构造了这个Demo

在这个function里面

进到这个fun以后

构造了这个Demo

在这个地方调用它的构造函数

在构造函数里面

有这样一行信息输出

所以

看到它的构造

接着呢

就输出一行信息

要抛出异常了

在func这个函数中要抛出异常

抛出了这个异常以后

紧接着我们就看到

Demo这个对象

Demo类型的对象d

它被析构了

然后才是捕获到异常进行处理

所以从这儿呢

我们观察到

不用担心进入try之后构造的

还没有析构的那些对象

它是能够正确被析构的

C++语言程序设计进阶课程列表:

第七章 继承与派生

-导学

--导学

-继承的基本概念和语法

--继承的基本概念和语法

-第七章 继承与派生--继承的基本概念和语法习题

-继承方式

--继承方式简介及公有继承

--私有继承和保护继承

-第七章 继承与派生--继承方式

-基类与派生类类型转换

--基类与派生类类型转换

-第七章 继承与派生--基类与派生类类型转换

-派生类的构造和析构

--派生类的构造函数

--派生类的构造函数举例

--派生类的复制构造函数

--派生类的析构函数

--第七章 继承与派生--派生类的构造和析构

-派生类成员的标识与访问

--访问从基类继承的成员

--虚基类

-第七章 继承与派生--派生类成员的标识与访问

-小结

--小结

-综合实例

--第七章综合实例

-实验七

--实验七

-第七章讲义

第八章 多态性

-导学

--导学

-第八章 多态性--导学

-运算符重载

--运算符重载的规则

--双目运算符重载为成员函数

--单目运算符重载为成员函数

--运算符重载为非成员函数

-第八章 多态性--运算符重载

-虚函数

--虚函数

--虚析构函数

--虚表与动态绑定

-第八章 多态性--虚函数

-抽象类

--抽象类

--第八章 多态性--抽象类

-override与final

--override与final

-第八章 多态性--override与final

-小结

--第八章小结

-综合实例

--第八章综合实例

-实验八

--实验八

- 第八章讲义

第九章 模板与群体数据

-导学

--导学

-模板

--函数模板

--类模板

-第九章 模板与群体数据--模板

-线性群体

--线性群体的概念

-第九章 模板与群体数据--线性群体

-数组

--数组类模板

--例9-4数组类应用举例

-链表

--链表的概念与结点类模板

--链表类模板

-第九章 模板与群体数据--链表

-栈

--栈类模板

--栈类模板课后习题

--例9-9 栈的应用

--例9-9 栈的应用课后习题

-队列

--队列类模板

-第九章 模板与群体数据--队列

-排序

--排序概述

--插入排序

--选择排序

--交换排序

-第九章 模板与群体数据--排序

-查找

--查找

--查找课后习题

-小结

--小结

-综合实例

--综合实例

-实验九

--实验九

- 第九章讲义

第十章 泛型程序设计与C++标准模板库

-导学

--导学

-泛型程序设计及STL的结构

--泛型程序设计的基本概念

--STL简介

-第十章 泛型程序设计与C++标准模板库--泛型程序设计及STL的结构

-迭代器

--迭代器

-第十章 泛型程序设计与C++标准模板库--迭代器

-容器的基本功能与分类

--容器的基本功能与分类

-第十章 泛型程序设计与C++标准模板库--容器的基本功能与分类

-顺序容器

--顺序容器的基本功能

--顺序容器的特征

--顺序容器的插入迭代器与适配器

--第十章 泛型程序设计与C++标准模板库--顺序容器

-关联容器

--关联容器分类和基本功能

--集合

--映射

--多重集合和多重映射

-第十章 泛型程序设计与C++标准模板库--关联容器

-函数对象

--函数对象

--函数适配器

-算法

--算法

-小结

--第十章小结

-综合实例

--综合实例

-实验十

--实验十

- 第十章讲义

第十一章 流类库与输入/输出

-导学

--导学

-I/O流的概念及流类库结构

--I/O流的概念及流类库结构

-第十一章 流类库与输入/输出--I/O流的概念及流类库结构

-输出流

--输出流概述

--向文本文件输出

--向二进制文件输出

--向字符串输出

-第十一章 流类库与输入/输出--输出流

-输入流

--输入流概述

--输入流应用举例

--从字符串输入

-第十一章 流类库与输入/输出--输入流

-输入/输出流

--输入/输出流

-第十一章 流类库与输入/输出--输入/输出流

-小结

--小结

-综合实例

--综合实例

-实验十一

--实验十一

- 第十一章讲义

第十二章 异常处理

-导学

--第12章导学

-异常处理的思想与程序实现

--异常处理的思想与程序实现

-第十二章 异常处理--异常处理的思想与程序实现

-异常处理中的构造与析构

--异常处理中的构造与析构

-第十二章 异常处理--异常处理中的构造与析构

-标准程序库异常处理

--标准程序库异常处理

-第十二章 异常处理--标准程序库异常处理

-小结

--第12章小结

-综合实例

--综合实例

-实验十二

--实验十二

- 第十二章讲义

异常处理中的构造与析构笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。