我有一个列表类,它包含一个pHead指针和一个典型的打印函数。我使用另一个函数(不在列表类中)将上面的列表作为其参数(非ref类型)并调用其print函数。当我调用这个“另一个函数”来打印列表时,它也调用析构函数打印后的列表这应该是那样的吗?有人可以向我解释一下吗? P.s:抱歉英语不好:P
答案 0 :(得分:2)
当对象超出范围时,析构函数会自动调用 :
在 case 中,会调用析构函数,因为当您传递列表类的对象时,它会在函数中创建该对象的副本,并且函数结束这个新创建的对象超出范围,因此调用析构函数。
修改:扩展到答案; 内存有三种主要类型
静态存储
void foo() { MyClass myclass_instance; myclass_instance.doSomething(); }
在上述情况下,当函数终止myclass_instance时会自动销毁。
对象驻留在动态内存(堆)中。它们被赋值为new,并且为了调用dstructor,你需要调用delete:
int main()
{
A* a = new A;
delete a; //destructor called
}
静态分配:对象驻留在静态内存中。无论它们在何处分配,程序结束时都会自动调用析构函数:
A a; //namespace scope
int main()
{
}
这里,当程序终止时,在主要完成后调用析构函数。
答案 1 :(得分:1)
如果对象达到其生命周期的末尾,即对象,则会调用析构函数,即
delete
(或delete[]
)分配的对象(对于具有动态存储持续时间的对象)致电new
(或new[]
)时new
operator 根据你的解释,我猜你通过按值传递它。当函数到达终点时,对象的副本也会达到其生命周期的末尾,因此会自动调用它的析构函数。
例如(Case x
表示对象tx
在此处被销毁):
struct T{
int a;
~T() { /* anything */ }
} t5;
struct U{
T t3;
};
void foo() {
T t1;
} // Case 1
int main() {
foo();
// Case 1
T *pt2 = new T();
delete pt2; // Case 2
{
U u1;
} // Case 3
void *buf = malloc(1000);
T *pt4 = new(buf) T();
pt4 -> ~T(); // Case 4
return 0; // Case 5
}