C++:析构函数的调用时机
结论:只有当类的某个实例化对象的构造函数执行完毕,而且当该对象退出作用域时,才会执行析构函数。
如果在执行构造函数的过程中抛出了异常,就不会调用析构函数
上测试代码:
1 class Test 2 { 3 public: 4 Test() 5 { 6 cout << "Test() begin..." << endl; 7 throw(0); 8 cout << "Test() end" << endl; 9 } 10 ~Test() 11 { 12 cout << "~Test()" << endl; 13 } 14 }; 15 16 int main() 17 { 18 try 19 { 20 Test t1; 21 } 22 catch (...) 23 { 24 cout << "........................................." << endl; 25 } 26 return 0; 27 }
执行结果:
推出这么一种不安全的情况
1 class Example 2 { 3 public: 4 Example() 5 { 6 m_p1 = new int[100]; 7 m_p2 = new int[100]; //如果这句代码抛出异常,则m_p2已经分配的资源会自动释放 8 //但是由于Example的构造函数尚未完全执行,因此当离开作用域时 9 //Example的析构函数不会被执行,导致m_p1分配的资源永远不会被释放 10 //ps:若是对象的构造函数尚未执行完全但是当对象退出作用域时仍然执行析构函数会发生什么? 11 //ps:在此种情况下,m_p2明明已经没有任何资源被它管理了,它最后却依然被delete[],仍然造成不合理的结果 12 } 13 ~Example() 14 { 15 delete[] m_p1; 16 delete[] m_p2; 17 } 18 private: 19 int* m_p1; 20 int* m_p2; 21 };
进一步推出结论:在一个类中不要管理多个资源,如果必须要管理多个资源,则创建多个资源管理类,将这些资源一对一滴分配给资源管理类来进行管理,再将资源管理类作为成员放在目标类中。