析构函数中的引用返回值和值更新

时间:2018-06-15 16:28:47

标签: c++ c++11 destructor

#include <iostream>
using namespace std;

int i; //1 - global

class Test
{
public:
    ~Test()
    {
        i = 10;
    }
};

int& foo()
{
    int i = 3; //2 - local
    Test ob;
    return i;
}

int main()
{
    cout << "i = " << foo() << endl; // output: i = 3
    return 0;
}

我对以上代码有疑问:

  1. 变量i是foo的本地变量,无法使用其引用(自动变量)。上面的代码是如何执行的?

  2. foo函数中的Test对象将在return语句后被销毁。 foo函数如何返回2(i = 3)的引用?

3 个答案:

答案 0 :(得分:4)

  

变量ifoo的本地变量,无法使用其引用(自动变量)。上面的代码如何执行?

您正在做的是导致未定义的行为。不幸的是,看似理智的行为也属于不明确的行为。 A legendary answer on SO阐述了这一主题。

  

返回语句后,Test函数中的foo对象将被销毁。 foo函数如何返回2(i = 3)的引用?

第一个陈述是正确的。但是,这与从i返回foo的问题无关。无论foo做什么,Test都会返回对函数局部变量的引用。

答案 1 :(得分:2)

您始终阅读并撰写全球i,因为您从未在代码中声明本地i或班级成员i

答案 2 :(得分:1)

当您致电foo()

cout << "i = " << foo() << endl;

这段代码将执行

int& foo() {
    i = 3; //2 - local
    Test ob; /* object having local scope */
    return i;
}/* when it goes out of this block.. destructor gets called */
上面的

是创建对象ob。当它超出范围时,析构函数~Test() { }会自动调用&amp;在destructor中您有i=10,因此return i;将返回析构函数中的i值。因此它将i值打印为10。另外,i = 3;不会创建新的i,它会考虑全局声明的i

更新代码:

int& foo() {
    int i = 3; /* here i is locally created */
    Test ob;
    return i; /* you can't return reference to local variable.. invokes UB */
}

以上代码块将导致未定义的行为。