堆栈内存由动态分配的对象成员变量引用

bjs*_*123 3 c++ visual-studio-2008

我有以下代码

class Test
{
public:
    int &ref;
    int a;

    Test(int &x)
        :ref(x)
    {
        cout<<"Address of reference "<<&ref<<endl;
        cout<<"&a : "<<&a<<endl;
        cout<<"this = "<<this<<endl;
    }
};

int main()
{
    Test *pObj = NULL;
    {
        int i = 10;
        cout<<"Address of referent "<<&i<<endl;
        pObj = new Test(i);
    }
    pObj->ref++;
    cout<<pObj->ref;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Address of referent 002DFB3C

Address of reference 002DFB3C

&a : 00734C94

this = 00734C90
Run Code Online (Sandbox Code Playgroud)

如您所见,Test对象是动态创建的.存储在堆栈中的变量i作为参数发送到Test类的构造函数.我打印了变量i,ref和a的地址.

问题:一旦程序控制退出声明它的块,变量i将被销毁.但动态分配对象的成员变量ref仍然会引用堆栈地址(i的地址).能够在我死后使用ref.

为什么堆对象有引用堆栈内存?为什么允许这样做?

Jam*_*lis 8

为什么堆对象有堆栈内存的引用?

因为您通过i引用将局部变量传递给Test动态创建的对象的构造函数,所以构造函数存储了该引用.

为什么允许这样做?

在C++中,程序员负责确保您使用的任何指针指向有效对象.这种语言没有任何保护措施来"保护"你做这样的愚蠢的事情(当然,有一些好的编程实践可以帮助你确保你编写的代码不应该有这样的问题).

在生命周期结束后尝试使用对象会导致未定义的行为.