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

C++ 为什么析构函数不修改返回的变量,c++,C++,下面的代码使用一个析构函数来修改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
。当析构函数运行时,
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: %d\n", thing());
}
#包括
类析构函数{
int&i;
公众:
析构函数(int&_i):i(_i){
~Destruct(){
i=2;
}
};
int thing(){
int i=-1;
破坏d(i);
返回i;
}
int main(){
printf(“i:%d\n”,thing());
}

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

如果您通过将thing中的
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: %d\n", thing());
}
#包括
int i=-1;
类析构函数{
int&i;
公众:
析构函数(int&_i):i(_i){
~Destruct(){
i=2;
}
};
int&thing(){
破坏d(i);
返回i;
}
int main(){
printf(“i:%d\n”,thing());
}
当函数返回时,对象
d
被销毁,堆栈清理开始!在调用析构函数时,返回值已复制到返回寄存器

通过执行以下操作,可以看到您想要看到的内容:

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

根据您的评论:

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

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


正如@Luc Touraille(在评论中)所问的那样:“如果您的函数返回
d
,您确定要在
d
传递给调用方之前将其销毁吗?”

这就是它的工作原理,代码的反汇编表明情况就是这样。我很好奇为什么。@user1290696:因为在return语句之前销毁对象毫无意义:如果函数返回
d
?您确定要在传递给调用方之前对
d
进行销毁吗?为什么更改为通过引用返回有效?为什么按值返回不显示所需的输出?因为按值返回会将i的值复制到另一个位置。此时该值仍然为-1。然后执行析构函数,更改对象中i的值。对象的“i”和返回的i副本是不同的变量,在内存中有不同的位置。基本上,按值返回会生成一个副本,而按引用返回只是对原始变量的引用。请记住,析构函数在return语句的效果得到解决后运行。
int thing() {
    int i = -1;
    {
        Destruct d(i);  //put it inside braces!
    }
    return i;
}