2

下面的代码使用了一个析构函数来修改i. 当析构函数运行时,2应该被存储到返回ithing()我们观察到-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());
}
4

2 回答 2

12
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被破坏吗?”

于 2012-07-27T11:00:00.643 回答
3

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

如果您通过使 in 事物全局化并通过引用返回来更改程序,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());
}
于 2012-07-27T10:59:46.363 回答