我有以下代码
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;
}
输出是:
Address of referent 002DFB3C Address of reference 002DFB3C &a : 00734C94 this = 00734C90
如您所见,正在动态创建Test对象。存储在堆栈中的变量i作为参数发送到Test类的构造函数。我打印了变量i,ref和a的地址。
问题:一旦程序控制退出声明它的块,变量i将被销毁。但动态分配对象的成员变量ref仍然会引用堆栈地址(i的地址)。能够在我死后使用ref。
为什么堆对象有引用堆栈内存?为什么允许这样做?
答案 0 :(得分:8)
为什么堆对象有堆栈内存的引用?
因为您通过引用将局部变量i
传递给动态创建的Test
对象的构造函数,所以构造函数存储了该引用。
为什么允许这样做?
在C ++中,程序员负责确保您使用的任何指针指向有效对象。这种语言没有任何保护措施来“保护”你做这样的愚蠢的事情(当然,有很好的编程实践可以帮助你确保你编写的代码不应该有这样的问题)。
在对象生命周期结束后尝试使用该对象会导致未定义的行为。