Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “怎么办?”;“丢失”;堆栈对象?_C++_Object_Stack - Fatal编程技术网

C++ “怎么办?”;“丢失”;堆栈对象?

C++ “怎么办?”;“丢失”;堆栈对象?,c++,object,stack,C++,Object,Stack,比如说,口袋妖怪是一个类。考虑这个片段: Pokemon Eve(4,3); //call to constructor, creating first object on the stack Eve=Pokemon(3,5); //call to constructor again, creating a second object on the stack 这两个对象都是在堆栈上创建的。执行第二行后,无法再访问第一个对象(参数为4,3)。它怎么了?用什么术语来描述这个过程?垃圾收集?对象不

比如说,口袋妖怪是一个类。考虑这个片段:

Pokemon Eve(4,3); //call to constructor, creating first object on the stack
Eve=Pokemon(3,5); //call to constructor again, creating a second object on the stack

这两个对象都是在堆栈上创建的。执行第二行后,无法再访问第一个对象(参数为4,3)。它怎么了?用什么术语来描述这个过程?垃圾收集?

对象不是在堆上创建的,而是直接在堆栈上创建的,因此不会丢失任何空间(即,不会有无法访问的已分配空间)--分配只会重用通过初始化
Eve
分配的内存


编辑:关于“覆盖”争用的措辞更为谨慎。

对象不是在堆上创建的,而是直接在堆栈上创建的,因此不会丢失任何空间(即,没有无法访问的已分配空间)--分配只是重用通过初始化
Eve
分配的内存


编辑:围绕“覆盖”争论的措辞更加谨慎。

我想你误解了正在发生的事情。最初创建为
Eve
的对象在第二行之后没有“丢失”。事实上,之后它仍然是相同的对象(我的意思是它仍然有相同的内存地址)。第二行通过调用对象
Eve
上的赋值运算符为对象赋值。传递给赋值操作符的参数是由
Pokemon(3,5)
创建的临时对象

它是所说的临时对象-
口袋妖怪(3,5)
,在第二行之后被销毁。它的销毁不是“垃圾收集”,甚至不是堆释放,因为它首先是一个堆栈对象,因此不需要这样做

我认为您是从Java/C或类似的托管语言的角度来考虑这一点的,这些语言只有对象引用,没有直接对象。在C++中,上面的代码直接处理对象。要看到与你头脑中所想的相当的东西,请考虑如下:

Pokemon* Eve = new Pokemon(4,3); 
Eve=new Pokemon(3,5); 

这里我们使用的是指针和堆,而不是堆栈。在本例中,第二行确实“丢失”了原始对象,因为它是重新分配的指针。这在某种程度上类似于Java/C中发生的情况,只有普通赋值。不同的是,当然,C++没有垃圾回收器,所以在上面,原始对象在内存泄漏中真正失去了。

我认为你误解了正在发生的事情。最初创建为
Eve
的对象在第二行之后没有“丢失”。事实上,之后它仍然是相同的对象(我的意思是它仍然有相同的内存地址)。第二行通过调用对象
Eve
上的赋值运算符为对象赋值。传递给赋值操作符的参数是由
Pokemon(3,5)
创建的临时对象

它是所说的临时对象-
口袋妖怪(3,5)
,在第二行之后被销毁。它的销毁不是“垃圾收集”,甚至不是堆释放,因为它首先是一个堆栈对象,因此不需要这样做

我认为您是从Java/C或类似的托管语言的角度来考虑这一点的,这些语言只有对象引用,没有直接对象。在C++中,上面的代码直接处理对象。要看到与你头脑中所想的相当的东西,请考虑如下:

Pokemon* Eve = new Pokemon(4,3); 
Eve=new Pokemon(3,5); 
这里我们使用的是指针和堆,而不是堆栈。在本例中,第二行确实“丢失”了原始对象,因为它是重新分配的指针。这在某种程度上类似于Java/C中发生的情况,只有普通赋值。不同的是,当然,C++没有垃圾回收器,所以在上面的原始对象在内存泄漏的意义上确实丢失了。

< P>它被称为“赋值操作符”,或者“=”.< /P> 第二个对象是临时对象,而不是第一个。构造后,调用第一个对象的赋值运算符,将第二个对象的值赋值给第一个对象

然后调用第二个对象的析构函数,第二个对象被销毁。它去哪里了?给天上的大水桶。它不见了。

它被称为“赋值运算符”,或“=”

第二个对象是临时对象,而不是第一个。构造后,调用第一个对象的赋值运算符,将第二个对象的值赋值给第一个对象


然后调用第二个对象的析构函数,第二个对象被销毁。它去哪里了?给天上的大水桶。它不见了。

我不会说分配的空间被“简单地覆盖”。C++赋值操作符可以在重写任何东西之前做多个事情。它可能根本不会覆盖任何内容,这取决于
操作符=()
的实现!这正是默认实现所发生的事情,而且,可以说,这是任何理智的重写都应该做的事情,就赋值语义而言。诚然,这个问题提供了一个极好的机会来插入对C++中的特殊操作符的深入咆哮,但是我非常怀疑OP是这么做的。这是真的,这就是为什么我没有投票。这完全取决于OP的
Pokemon
类中发生了什么。重写
operator=()
最明显的原因是对指针进行深度复制,而不仅仅是“简单地重写”类内容。我的评论更多的是为了指出,我们不必对OP的
口袋妖怪
类做出假设,也不必做笼统的陈述。我不会说分配的空间“只是被覆盖了”。C++赋值操作符可以在重写任何东西之前做多个事情。它可能根本不会覆盖任何内容,这取决于
操作符=()
的实现!这正是默认情况下发生的情况