返回值会发生什么?

时间:2015-05-01 00:25:15

标签: c++ pointers return

所以这个例子我有两个班:
E,在销毁时打印消息+可以存储整数值
T,它存储E的实例并可以通过方法

返回它

代码:

class E
{
public:
    E();
    ~E();
    int test;
};

E::E(){}
E::~E()
{
    std::cout << "E is destroyed" << std::endl;
}

///////////////////////////////////////////

class T
{
public:
    T();
    ~T();
    E data;
    E get();
};

T::T(){}
T::~T(){}
E T::get()
{
    return this->data;
}

///////////////////////////////////////////

int main()
{
    E e;
    e.test = 2;

    T t;
    t.data = e;

    E* e2;
    {      
        e2 = &(t.get());
        std::cout << "end of block" << std::endl;
    }

    std::cout << e2->test;
}

运行我的代码的结果是:

E is destroyed
end of block

这意味着E的某个实例在到达{}

结束之前被销毁

问题:
我试验了一下。 t.get()行中的e2 = &(t.get());值是否被立即销毁是正确的,因为它没有按值分配给任何变量?
2.如果此值被销毁,则表示e2指针无效。但是std::cout << e2->test;行仍然会打印保存的整数值。指针在某种程度上是否仍然有效,或者这些数据偶尔会停留在这个记忆位置?

1 个答案:

答案 0 :(得分:2)

原始代码不会由GCC编译,因为函数

E T::get()
{
    return this->data;
}

返回值。在块中指定指针e2 = &(t.get());时,它会生成data的临时副本。退出块后,当您引用指针e2时,它不再指向实际变量,因为临时变量超出了范围。因此,为了更正此问题,您可以修改代码以返回对data类的T字段的引用:

E& T::get()
{
    return data;
}

之后再次运行代码时,您会看到:

end of block
2
E is destroyed
E is destroyed

请注意,这两个E is destroyed是因为有两个E个实例,一个用于e,另一个用于t.data,因为代码{{ 1}}将调用类t.data = e;的复制构造函数。因此,当程序退出时,最终会有两个E个对象被破坏。