为什么析构函数不修改返回的变量

Why does the destructor not modify a variable being returned

本文关键字:变量 返回 修改 析构函数 为什么      更新时间:2023-10-16

下面的代码使用了一个修改i的析构函数。当析构函数运行时,2应该存储在i中,但当thing()返回时,我们观察到-1

#include <stdio.h>
class Destruct {
    int &i;
public:
    Destruct(int &_i) : i(_i) {}
    ~Destruct() {
        i = 2;
    }
};
int thing() {
    int i = -1;
    Destruct d(i);
    return i;
}
int main() {
    printf("i: %dn", thing());
}
int thing() {
    int i = -1;
    Destruct d(i);
    return i;
}

当函数返回时,对象d将被销毁,堆栈清理开始!在调用析构函数时,返回的值已经复制到返回寄存器中。

你想看到的,可以通过这样做来看到:

int thing() {
    int i = -1;
    {
        Destruct d(i);  //put it inside braces!
    }
    return i;
}

根据您的评论:

这就是它的工作原理,代码的反汇编表明情况就是这样。我很好奇为什么。

逻辑很简单,可以这样证明:假设在i复制到返回寄存器之前调用了析构函数,那么为什么要选择性地销毁d而不销毁i呢?毕竟两者都是局部变量。因此,如果d被破坏,那么i也应该被破坏,在之前,它的值被复制到返回寄存器,但这没有意义

正如@Luc Touraille(在评论中)所问:"如果你的函数返回d怎么办?你确定你希望d在传递给调用者之前被销毁吗?"

因为析构函数是在复制语句return i中的i之后执行的。

如果你通过将i设置为全局并通过引用返回来更改你的程序,你会看到你想要的。

#include <stdio.h>
int i = -1;
class Destruct {
    int &i;
public:
    Destruct(int &_i) : i(_i) {}
    ~Destruct() {
        i = 2;
    }
};
int& thing() {
    Destruct d(i);
    return i;
}
int main() {
    printf("i: %dn", thing());
}