我注意到,当程序结束时我声明一个对象的指针时,不会调用析构函数。这是我尝试的代码:
class B {
public:
B(){cout<<"cons B;"; };
B(const B &b ){cout<<"copy B;"; };
~B(){cout<<"Destr B;"; };
};
class Y:public B {
public:
Y(){cout<<"cons Y;"; };
Y(const Y &y ){cout<<"copy Y;"; };
~Y(){cout<<"Destr Y;"; };
};
int main(){
Y *y= new Y;
f(y);
}
不调用析构函数,结果为:cons B cons Y 另一方面,如果我运行此代码:
Y y;
调用析构函数,结果为:cons B cons Y dest Y dest B
我的问题是为什么在第一个程序中没有调用析构函数?
答案 0 :(得分:1)
对象的析构函数在对象被销毁时(而不是在程序退出时)被调用。在您的代码中,您永远不会破坏对象。
您无意中造成了内存泄漏。
在完成处理后或在退出应用程序之前销毁对象,并将调用其析构函数。
int main(){
Y *y= new Y;
f(y);
delete y;
}
答案 1 :(得分:0)
您已经使用new运算符在堆中创建了Class对象,在堆中,每当我们创建对象时,我们都有责任删除动态创建的内存。 因此,我们需要显式调用delete释放内存,一旦使用delete它将导致对析构函数的调用。
答案 2 :(得分:0)
很容易忘记,如果要从高级语言进行迁移,则没有垃圾收集器。经验法则是,每当您使用new时,完成后都使用delete。即使在函数或程序结束后,指针也将保持存在。可以说,它们的用途是生成一些数据的函数。如果使用指针,则函数结束并释放其堆栈后,可以继续使用该模型。小心使用指针,并确保它们有时会被删除,而不必在同一函数中。
指针就像一个储蓄箱。您可以通过取消引用并更改其内容来初始化一个并转到它。您还可以将保管箱传递给其他人,并允许他们像您所做的那样修改并看到相同的内容,而不是仅仅给他们那里所有内容的副本。保管箱在最初创建该保管箱的人通过后将保持存在,因为其他人也可以使用和编辑其内容。