本文共 2401 字,大约阅读时间需要 8 分钟。
析构函数在下边3种情况时被调用:
第一种情况
#includeusing namespace std;class A{public: A() { cout << "constructing A" << endl; } ~A() { cout << "destructing A" << endl; }private: int a;};void main(){ A a;}
运行结果:
constructing Adestructing A
第二种情况
如果是new的对象,即使离开了作用域也会一直存在,必须主动delete,否则只有在结束程序时才会执行析构。这里在说下内存泄漏,举个例子
#includeusing namespace std;class A{public: A() { cout << "constructing A" << endl; } ~A() { cout << "destructing A" << endl; }private: int a;};void fun() { A *a = new A();}int main() { while (1) { fun(); } return 0;}
当离开fun时,虽然离开了作用域,但用new动态开辟空间的对象是不会析构的,你可以观察任务管理器,看到内存一直在上升。但你在其他地方确无法使用a所开辟的空间,因为a这个指针是保存在栈上的,当离开作用域后就自动析构(或者说自动消失了),但它所在分配空间是分配在堆上的,只有主动析构或程序结束,才会释放空间,也就是丢失了这块空间的地址,无法操作这块空间了 。
第三种情况
#includeusing namespace std;class A{public: A() { cout << "constructing A" << endl; } ~A() { cout << "destructing A" << endl; }private: int a;};class C{public: C() { cout << "constructing C" << endl; } ~C() { cout << "destructing C" << endl; }private: int c;};class B : public A{public: B() { cout << "constructing B" << endl; } ~B() { cout << "destructing B" << endl; }private: int b; C c;};void main(){ B b;}
运行结果:
constructing Aconstructing Cconstructing Bdestructing Bdestructing Cdestructing A
B的析构函数调用之后,又调用了B的成员c的析构函数 。
若将上边的代码中的main()函数内容改成
A* a = new B; delete a;
我们知道,这将不会调用class B的析构函数不会被调用,所以class C的析构函数也不会被调用。
运行结果:
constructing Aconstructing Cconstructing Bdestructing A
若将class A中的析构函数声明为虚函数 ,这时class B的析构函数也会被调用,例如:
#includeusing namespace std;class A{public: A() { cout << "constructing A" << endl; } virtual ~A() { cout << "destructing A" << endl; }private: int a;};class C{public: C() { cout << "constructing C" << endl; } ~C() { cout << "destructing C" << endl; }private: int c;};class B : public A{public: B() { cout << "constructing B" << endl; } ~B() { cout << "destructing B" << endl; }private: int b; C c;};void main(){ A* a = new B; delete a;}
运行结果:
constructing Aconstructing Cconstructing Bdestructing Bdestructing Cdestructing A
此文章参考了:
转载地址:http://diwab.baihongyu.com/