异常问题
先说一个大家都知道的现象(既然都知道,好像就没有必要说了,但是为了讨论方便,还是提一下吧,哈哈)。
如果一个局部对象的构造函数没有被成功调用(在执行构造函数时抛出了一个异常),那么在函数“栈展开”时应该不会调用此对象的析构函数,因为C++不会析构“不完整的对象”。如下:
class foo{
public:
int a;
foo() { a = 33; throw 1; }//构造函数中抛出异常
~foo() { cout << a << endl; }
};
void test(){
foo f;
}
void main(int argc, char **argv)
{
try{
test();
}
catch(...){
}
}
程序并不会显示“33”,因为在退出test()执行“栈展开”时并没有调用f的析构函数。
但是如果把foo构造函数中的"throw 1"转移到test函数的结尾处,运行结果就会显示“33”,说明此时编译器在“栈展开”时调用了“完整”对象f的析构函数。
我的问题是:编译器在退出test()执行“栈展开”时怎么知道栈中的f是“不完整的对象”?难道对象本身会带有某些“标记”来标识自己是“不完整”的?或者是通过其他的途径让编译器不去调用f的析构函数?
高手指教,谢谢
如果一个局部对象的构造函数没有被成功调用(在执行构造函数时抛出了一个异常),那么在函数“栈展开”时应该不会调用此对象的析构函数,因为C++不会析构“不完整的对象”。如下:
class foo{
public:
int a;
foo() { a = 33; throw 1; }//构造函数中抛出异常
~foo() { cout << a << endl; }
};
void test(){
foo f;
}
void main(int argc, char **argv)
{
try{
test();
}
catch(...){
}
}
程序并不会显示“33”,因为在退出test()执行“栈展开”时并没有调用f的析构函数。
但是如果把foo构造函数中的"throw 1"转移到test函数的结尾处,运行结果就会显示“33”,说明此时编译器在“栈展开”时调用了“完整”对象f的析构函数。
我的问题是:编译器在退出test()执行“栈展开”时怎么知道栈中的f是“不完整的对象”?难道对象本身会带有某些“标记”来标识自己是“不完整”的?或者是通过其他的途径让编译器不去调用f的析构函数?
高手指教,谢谢
...全文
相关推荐
BL2_skingen-1.2.4-cp38-cp38-win_amd64.whl
BL2_skingen-1.2.4-cp38-cp38-win_amd64.whl
如何通过异常堆栈定位线上问题
我们可以在代码中插入日志语句,在异常发生的位置和相关方法中记录一些关键变量的值。通过仔细分析异常堆栈,我们可以确定异常发生的原因和可能的修复点。其中,异常堆栈信息是非常有用的工具,可以帮助我们快速定位问题的源头。我们应该仔细阅读堆栈信息,查找我们自己代码中的方法调用链,并寻找异常发生的根源。查看异常类型和消息:异常类型可以告诉我们异常的具体类型,而异常消息通常包含了一些关键信息,例如错误的输入数据或者无法访问的资源。当异常发生时,异常堆栈信息将被打印出来,我们可以看到异常发生的位置和调用链。
BL2_skingen-1.2.3-cp38-cp38-win_amd64.whl
BL2_skingen-1.2.3-cp38-cp38-win_amd64.whl
《模式识别与数据挖掘》配套PPT课件
《模式识别与数据挖掘》配套PPT课件
科技成果转化项目进场交易前,评估备案环节需要准备哪些材料?_8.docx
科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。


