06异常对象的生命周期(根据catch的参数类型判断)
1 catch捕获时可能的参数类型
1)普通类型元素(包括对象)。
2)引用。
3)指针。
2 代码测试
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class MyException {
public:
MyException() {
cout << "构造函数!" << endl;
}
MyException(const MyException& ex) {
cout << "拷贝构造!" << endl;
}
// 不会被调用
void operator = (const MyException &other) {
cout << "等号重载" << endl;
}
~MyException() {
cout << "析构函数!" << endl;
}
};
void func() {
throw MyException();
//throw &(MyException()); //创建匿名对象 调用构造
// throw new MyException;
}
void test01() {
try {
func();
}
catch (MyException e) {
cout << "异常捕获!" << endl;
//delete e;
}
// catch中的可能参数类型:普通类型元素 引用 指针
// 1 普通元素 异常对象catch处理完之后就析构
// 2 引用 不用调用拷贝构造(因为匿名对象转正),异常对象catch处理完之后就析构
// 3 指针 异常对象catch处理完之前就析构
}
int main(void) {
test01();
return 0;
}
3 代码测试结果
1)抛出匿名对象-catch类型为普通类型元素时:
两次析构一个是因为匿名对象,一个是因为catch的局部变量e。
2)匿名对象-引用:
不用调用拷贝构造(因为匿名对象转正,即同一个对象),异常对象catch处理完之后就析构。
3)匿名对象地址-指针时:
指针指向抛出的地址,只是简单的等号赋值,不会调用等号重载运算符。但是catch是指针类型时,即抛出的是对象地址时,就需要额外注意,它在内存中是先被释放掉再处理异常信息,这一点与普通元素是不一样的(应该与内部机制有关,只允许对象处理完异常信息才允许释放)。
解决方法:使用new处理的地址抛出,处理完异常信息后必须记得自行释放。
4 总结异常对象的生命周期
1)普通元素:异常对象catch处理完之后就析构。
2)引用:不用调用拷贝构造(因为匿名对象转正),异常对象catch处理完之后就析构。
3)指针:异常对象catch处理完之前就析构。注意,是之前,解决是抛出new的地址。