任何人都可以解释在cpp
中创建的对象的范围#include <iostream>
using namespace std;
class box
{
public:
int i;
box* doubled ();
};
box* box::doubled ()
{
box *temp = new box;
temp->i = 2*this->i;
return temp;
}
int main ()
{
box *obj1 = new box;
obj1->i = 5;
box *obj2;
obj2 = obj1->doubled();
delete obj1;
cout << "i = " << obj2->i << endl;
return 0;
}
在上面的示例代码中,obj2是一个指针,用于保存由 Doubled 函数创建的内存。 temp的范围应仅对doubled函数有效,但也可以在main函数中访问。
任何人都可以解释为什么会这样。我想这是一个小小的疑问,但却无法理解。
答案 0 :(得分:4)
您没有删除在函数doubled
中动态创建的对象,因此当然指向它的指针仍然有效。运算符new
动态分配对象,它们保留在内存中直到被明确销毁。只有指向内存地址的指针(temp
变量)被销毁,但由于你返回了它的值(地址),内存仍然属于一个程序。实际上不删除会造成内存泄漏。
如果希望在范围结束后删除对象,则应使用std::unique_ptr
。
以下是没有动态分配的简单示例:
T* foo ()
{
T T_instance;
return &T_instance;
}
它甚至不应该使用类似于returning address of local variable or temporary
的消息进行编译,表明在程序退出T_instance
后foo()
将被销毁。
答案 1 :(得分:2)
执行此操作时:
box *temp = new box;
您创建一个超出所有范围的动态分配的box
对象,以及一个名为box*
的{{1}},它位于本地范围内。您必须通过在指向它的指针上调用temp
来自行释放动态分配的对象,例如,如下所示:
delete
在上面的代码行中唯一尊重范围的是实际指针delete temp;
,它指向该对象。
temp
答案 2 :(得分:1)
doubled
的返回值是由new
分配的指针。此指针的值是堆上box
对象的地址,因此虽然temp
是临时的,但其值存储在此行的obj2
obj2 = obj1->doubled();
所以当您通过obj2
访问数据时,它仍然有效。