Joh*_*ohn 13 c++ exception raii
我刚刚开始使用C++中的RAII并设置一个小测试用例.要么我的代码深感困惑,要么RAII无效!(我想这是前者).
如果我跑:
#include <exception>
#include <iostream>
class A {
public:
A(int i) { i_ = i; std::cout << "A " << i_ << " constructed" << std::endl; }
~A() { std::cout << "A " << i_ << " destructed" << std::endl; }
private:
int i_;
};
int main(void) {
A a1(1);
A a2(2);
throw std::exception();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
除了注释外我得到:
A 1 constructed
A 2 constructed
A 2 destructed
A 1 destructed
Run Code Online (Sandbox Code Playgroud)
正如所料,但除了我得到:
A 1 constructed
A 2 constructed
terminate called after throwing an instance of 'std::exception'
what(): std::exception
Aborted
Run Code Online (Sandbox Code Playgroud)
所以即使它们超出范围,我的物体也不会被破坏.这不是RAII的全部基础.
指针和更正非常感谢!
Aar*_*ela 20
您没有处理异常的处理程序.当发生这种情况时,标准说调用std :: terminate,然后调用abort.请参阅"C++编程语言"第3版第14.7节.
jal*_*alf 17
问题是main具有特殊地位.当从那里抛出异常时,堆栈无法有意义地展开,应用程序只是调用它std:terminate.
然后,为什么变量不会超出范围,这有点道理.我们实际上没有离开宣布它们的范围.可以认为发生的事情与此相同:
int main(void) {
A a1(1);
A a2(2);
std::terminate();
}
Run Code Online (Sandbox Code Playgroud)
(我相信它是实现定义的,但是在这种情况下是否会调用析构函数,所以在某些平台上,它会像你期望的那样工作)
你在main中有一个unhanded异常,这意味着一个终止的调用.试试这个:
int main(void)
{
try
{
A a1(1);
A a2(2);
throw std::exception();
return 0;
}
catch(const std::exception & e)
{
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
如果一个异常转义为main(),那么实现定义的天气是堆栈被解开的.
尝试
int main()
{
try
{
doWork(); // Do you experiment here.
}
catch(...)
{ /*
* By catching here you force the stack to unwind correctly.
*/
throw; // re-throw so exceptions pass to the OS for debugging.
}
}
Run Code Online (Sandbox Code Playgroud)
正如其他人所指出的,你有一个未被捕获的异常,它调用terminate().它是实现定义的(参见标准,15.3第9段和第15.5.1段第2段)是否在这种情况下调用析构函数,并且实现中的定义显然是"否,它们不会".(如果因抛出没有处理程序的异常而调用terminate(),则不会调用析构函数.)
| 归档时间: |
|
| 查看次数: |
1299 次 |
| 最近记录: |