所以这个例子我有两个班:
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;
行仍然会打印保存的整数值。指针在某种程度上是否仍然有效,或者这些数据偶尔会停留在这个记忆位置?
答案 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
个对象被破坏。