析构函数通常什么情况下不会调用?

情况1:基类指针指向派生类对象,delete基类指针不会调用派生类的析构函数

  1. #include <iostream>
  2. using namespace std;
  3. class A{
  4. public:
  5. A(){cout << "A:A()" << endl;}
  6. ~A(){cout << "A:~A()" << endl;}
  7. };
  8. class B: public A{
  9. public:
  10. B(){cout << "B:B()" << endl;}
  11. ~B(){cout << "B:~B()" << endl;}
  12. };
  13. int main(){
  14. A* a = new B();
  15. delete a;
  16. cout << endl;
  17. A* a1;
  18. B* b = new B();
  19. a1=b;
  20. delete a1;
  21. return 0;
  22. }
  1. // 以下是程序输出
  2. A:A()
  3. B:B()
  4. A:~A()
  5. A:A()
  6. B:B()
  7. A:~A()
  8. Process returned 0 (0x0) execution time : 0.020 s
  9. Press any key to continue.

如果在delete a1;之后,再执行delete b;,则会报错(对同一内存区域释放两次内存)。

情况2:new/new[]得到的对象,在对象声明周期结束后,不会自动调用对应的delete/delete[],也就无法调用析构函数释放空间

#include <iostream>
using namespace std;

class A{
public:
    static int id_count;
    int id;
    A(){
        id=A::id_count++;
        cout << "A:A(" << this->id << ")" << endl;
    }

    A(int _a){
        id = _a;
        cout << "A:A(" << this->id << ")" << endl;
        A::id_count = _a+1;
    }

    ~A(){
        cout << "A:~A(" << this->id << ")" << endl;
    }
};

int A::id_count = 0;

int main(){
    {
        A a1;
    }

    cout << endl;
    {
        A* a2 = new A(5);
    }

    cout << endl;
    {
        A *a3[2];
        for(int i=0; i<2; i++){
            a3[i] = new A();
        }
    }

    return 0;
}
// 程序输出
A:A(0)
A:~A(0)

A:A(5)

A:A(6)
A:A(7)

Process returned 0 (0x0)   execution time : 0.016 s
Press any key to continue.

情况3:程序异常,过早结束

类A的代码同情况2,main()修改如下:

int main(){
    {
        A a1;

        int n=1;           // 使用变量而不直接用5/0可以欺骗编译器,使其不发出除0的警告
        if(5/--n){
            cout << "never output" << endl;
        }
    }

    return 0;
}
// 程序输出
A:A(0)

Process returned -1073741676 (0xC0000094)   execution time : 0.190 s
Press any key to continue.

程序遇到除0,异常结束,无法调用析构函数。