为什么我的析构函数被调用两次

Why is my destructor called twice?

本文关键字:两次 调用 我的 析构函数 为什么      更新时间:2023-10-16

假设我用以下方法给一个班级学生:

Student Student::method(Student x)
{
    //nothing important
    return x;
}

复制构造函数被调用两次,一次是在对象 x 作为参数发送时调用,第二次是在从函数返回 x 时调用。

当我调用此方法时,为什么以及何时调用类 Student 的析构函数两次?调用是这样的:a = b.method(c),其中 a、b 和 c 是 Student 对象。

对于您的示例,a = b.method(c); ,除了复制省略之外,可能会发生三个副本。第一种是将c对象复制到函数参数 x 中。第二个是从函数返回x对象时。第三种是将返回值复制到a对象中时。前两个涉及复制构造函数,最后一个涉及复制赋值运算符,除非您将其更改为 Student a = b.method(c); ,在这种情况下,它们都使用复制构造函数。

abc都将在其范围结束时被摧毁。对象x将在method函数结束时销毁。函数的返回值将在包含它的完整表达式的末尾销毁 - 也就是说,一旦a = b.method(c);完成。

但是,并非所有这些副本都必须发生 - 在某些情况下,编译器可以省略或省略类的复制/移动构造。将发生函数参数的第一次复制。在尝试复制函数之前,函数的第二个副本将首先被视为移动。可以省略此复制或移动。如果使用复制赋值,则最终副本(从临时返回值到 a)将发生,但如果使用复制构造函数(如 Student a = b.method(c); 所示),则可能会被省略。

如果构造了两个 Student 对象,则必须销毁它们。复制到参数和从返回值中复制需要销毁。

当函数返回时(x复制到返回值之后),将调用 x 的析构函数。

返回值的

析构函数在包含函数调用的完整表达式的末尾调用(除非返回值通过分配给引用而延长其生存期)。

构建的每个具有自动存储持续时间的对象都将自动销毁(通常以相反的构造顺序)。你构造两个对象(x和返回值),因此有两个析构函数调用。