企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
[TOC] # 栈解旋 异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上构造的所有对象,都会被自动析构。 析构的顺序与构造的顺序相反,这一过程称为栈的解旋(unwinding). # 异常的生命周期 ## 产生三个对象 ~~~ class Maker { public: Maker() { cout << "Maker的构造" << endl; } Maker(const Maker &m) { cout << "Maker的拷贝构造" << endl; } ~Maker() { cout << "Maker的析构" << endl; } }; void func() { //在抛出异常的函数中,如果抛出异常之后,但函数没有结束,这时,栈上申请的对象都会被释放 //这就叫栈解旋 Maker m; //第一个对象,在异常接收前被释放 cout << "--------" << endl; //第二个对象,是第一个对象拷贝过来的 throw m;//这个m是Maker m拷贝一份的,会调用拷贝构造 cout << "func函数结束" << endl; } void test02() { try { func(); cout << "func()代码后" << endl; } catch (Maker m) { //第三个对象,是第二个对象拷贝过来的 //第二个和第三个对象在catch结束时释放 cout << "接收一个Maker类型的异常" << endl; } } ~~~ 输出 ~~~ Maker的构造 -------- Maker的拷贝构造 Maker的析构 Maker的拷贝构造 接收一个Maker类型的异常 Maker的析构 Maker的析构 ~~~ ## 产生两个对象 ~~~ //产生二个对象 void func2() { //第一个对象 throw Maker();//匿名对象 } void test02() { try { func2(); } catch (Maker m1)//第二个对象 { cout << "接收一个Maker类型的异常" << endl; //第一个和第二个对象在catch结束时释放 } } ~~~ ## 产生一个对象 ~~~ //产生一个对象,常用这种方式 void func3() { throw Maker();//匿名对象 } void test03() { try { func3(); } catch (Maker &m1) { cout << "接收一个Maker类型的异常" << endl; } } ~~~ ## 取地址方式产生1个对象 ~~~ void func4() { //编译器不允许对栈中的匿名对象取地址操作 //throw Maker();//匿名对象 //编译器允许对堆区中的匿名对象取地址操作 throw new Maker(); } void test02() { try { func4(); } catch (Maker *m1) { cout << "接收一个Maker类型的异常" << endl; //delete m1; } } ~~~