目录
1.try-catch中的析构行为
预测下面程序输出结果:
#include <iostream>
using namespace std;
class Test {
public:
Test() { cout << "Constructing an object of Test " << endl; }
~Test() { cout << "Destructing an object of Test " << endl; }
};
int main() {
try {
Test t1;
throw 10;
}
catch (int i) {
cout << "Caught " << i << endl;
}
}
运行结果:
Constructing an object of Test
Destructing an object of Test
Caught 10
当抛出一个异常时,在catch代码块得到执行前,try中的对象会被析构。这就是为何上述程序 在“Caught 10″之前打印“Destructing an object of Test”的原因。
2.构造函数中抛出异常时的析构行为
如果是在构造函数中抛出异常,程序如何处理?
参考下面例子。
#include <iostream>
using namespace std;
class Test1 {
public:
Test1() { cout << "Constructing an Object of Test1" << endl; }
~Test1() { cout << "Destructing an Object of Test1" << endl; }
};
class Test2 {
public:
// 这个构造函数会抛出整形异常
Test2() {
cout << "Constructing an Object of Test2" << endl;
throw 20;
}
~Test2() { cout << "Destructing an Object of Test2" << endl; }
};
int main() {
try {
Test1 t1; // 构造与析构都被执行
Test2 t2; // 部分被构造
Test1 t3; // t3不会被构造,因为这个表达式一直不会执行。
}
catch (int i) {
cout << "Caught " << i << endl;
}
}
运行结果:
Constructing an Object of Test1
Constructing an Object of Test2
Destructing an Object of Test1
Caught 20
析构函数只会运行在已经完整的构造好的对象中。当某个对象在构造时抛出异常,则析构函数不会被调用到。
3.try-catch中对象的析构顺序
下面例子演示了对象的析构顺序。
#include <iostream>
using namespace std;
class Test {
static int count;
int id;
public:
Test() {
count++;
id = count;
cout << "Constructing object number " << id << endl;
if (id == 4)
throw 4;
}
~Test() { cout << "Destructing object number " << id << endl; }
};
int Test::count = 0;
int main() {
try {
Test array[5];
}
catch (int i) {
cout << "Caught " << i << endl;
}
}
运行结果:
Constructing object number 1
Constructing object number 2
Constructing object number 3
Constructing object number 4
Destructing object number 3
Destructing object number 2
Destructing object number 1
Caught 4
观察上面结果,可以看到析构的顺序与构造顺序相反。为什么会这样?
这是因为这些对象都是存储在栈内存上的,当析构时,是按照后进先出的顺序来析构对象。