为什么在抛出异常时析构函数调用两次
why destructor called twice when exception is thrown?
我很困惑,为什么在抛出excpetion时destrctor被调用两次,以及它们被调用了哪一点??
#include <iostream>
using namespace std;
class base
{
public:
base(){cout<<"constructor called"<<endl;}
~base(){cout<<"destructor called"<<endl;}
};
void fun()
{
throw base(); //<=- Create temp obj of base, and throw exception
}
int main()
{
try
{
fun();
}
catch(...)
{
cout<<"handle all exception"<<endl;
}
}
以下是输出
constructor called
destrctor called
handle all exception
destuctor is called
但当我添加复制构造函数时,它从未调用过,但析构函数只调用过一次,所以发生了什么????
#include <iostream>
using namespace std;
class base
{
public:
base(){cout<<"constructor called"<<endl;}
~base(){cout<<"destructor called"<<endl;}
base (base &obj){cout<<"copy constructor called"<<endl;}
};
void fun()
{
throw base(); //<=- Create temp obj of base, and throw exception
}
int main()
{
try
{
fun();
}
catch(...)
{
cout<<"handle all exception"<<endl;
}
}
输出:
constructor called
handle all exception
destrctor called
编译器可以随心所欲地复制异常对象。析构函数被调用两次,因为存在副本。
因为异常对象是在catch中复制的。使用catch (base&v)
通过引用而非值进行抓取。
因为catch
块获取原始对象的副本。
为了避免复制,将try-catch
写为:
try
{
fun();
}
catch(const base &e)
{
cout<<"handle all exception"<<endl;
}
我也想对设计进行评论:用户定义的异常类应该派生自std::exception
或其派生类之一。
相关文章:
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- C++析构函数调用两次,堆栈分配的复合对象
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- 为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取
- 为什么这个自定义分配器的析构函数在 GCC/MSVS 的 stdlib 中被调用两次
- 调用某个回调函数两次会导致分段错误:Nan
- 重载运算符 new(),为什么构造函数被调用两次?
- 为同一存储位置调用构造函数两次是否合法?
- 为什么在下面的代码中调用复制构造函数两次
- 为什么在这里调用析构函数两次
- while 循环在一个函数调用中执行两次
- 为什么这个构造函数被调用两次
- 析构函数在与 STL 的共享指针中调用两次
- 为什么在C 中超载邮政增量运算符两次调用构造函数
- 现代C++编译器是否能够避免在某些条件下两次调用常量函数
- 构造函数在不同线程中的静态单例类上调用两次
- 类析构函数在创建shared_ptr时调用两次
- 在c++中,使用指针的两个函数调用之间的区别是什么?
- 用define替换两次函数调用