C++构造函数异常(二)
继续上一篇文章提到的构造异常话题,下面继续谈另外两个场景,即多继承构造异常,以及智能指针构造异常
第3:对多继承当中,某个基类构造异常,而其他基类已构造成功,则构造成功的基类不会析构,由编译器负责回收
1 class B{ 2 3 public: 4 B(){ 5 age = 0; 6 cout << "construct B default" << endl; 7 throw 0;//抛出异常 8 } 9 10 ~B(){ 11 cout << "destructor B ,age=" << age << endl; 12 } 13 private: 14 int age; 15 }; 16 17 class C{ 18 public: 19 C(){ 20 //得到指定范围[m,n]的随机数:r = rand()%(n - m + 1) + m; 21 int r = rand()%(8-0)+0; 22 num = r; 23 cout << "constuctor C ,num = " << num << endl; 24 25 } 26 ~C(){ 27 cout << "destructor C, num = " << num << endl; 28 } 29 private: 30 int num; 31 }; 32 33 class D:public C, public B{ 34 35 public: 36 D(){ 37 cout << "constructor D " << endl; 38 } 39 40 ~D(){ 41 cout << "destrcutor D" << endl; 42 } 43 }; 44 45 int main(void){ 46 47 48 D d; 49 50 }
class B 默认构造函数抛出异常,而class C 默认构造函数是成功的,但并不会调用C的析构函数,由编译器回收
注释第7行的throw 0后则是下面结果:
第4:智能指针, 使用stl容器存放shared_ptr<T> 对象,若T构造函数发生异常,则前面成功构造的对象由编译器负责回收,见代码
1 class C{ 2 public: 3 C(){ 4 //得到指定范围[m,n]的随机数:r = rand()%(n - m + 1) + m; 5 int r = rand()%(8-0)+0; 6 num = r; 7 cout << "constuctor C ,num = " << num << endl; 8 if(!(r % 4)){ 9 throw r;//当随机数r为4的倍数时抛出异常 10 } 11 } 12 ~C(){ 13 cout << "destructor C, num = " << num << endl; 14 } 15 private: 16 int num; 17 }; 18 19 int main(void){ 20 21 typedef shared_ptr<C> spc; 22 vector <spc> vc; 23 for(auto i = 0; i < 10; i++){ 24 vc.push_back( spc(new C()) ); 25 } 26 }
结果如下:当C构造函数中num等于4直接throw 异常
若注释第9行的throw r,则vector中所有元素都构造成功,main函数结束,调用C析构函数
好了,大概就这几种情况,其他没有列举的场景,你不妨再试一下,我相信结果是一样的
结论:但构造函数发生异常,其之前成功构造的基类成员、类成员、初始化列表,stl存放的智能对象都由编译器负责回收,程序员无权过问,也不需过问。
以上所有代码都是在Ubuntu 14.04(64)测试,如果有问题,欢迎指出。