C ++移动构造函数和范围

时间:2014-03-22 19:57:46

标签: c++ scope copy-constructor move-constructor

如果我在堆栈上声明了一个对象,并且我返回对它的引用,我相信我将无法再访问它,因为它超出了范围。正确的吗?

如果我只返回对象本身(不是对它的引用)怎么办?是否会调用复制构造函数? (我听过“移动构造函数”这个术语,但从我读到的内容来看,这似乎是一个新特性。任何人都能详细说明一下吗?)

在哪些情况下会调用析构函数?

3 个答案:

答案 0 :(得分:3)

  

如果我在堆栈上声明了一个对象,并且我返回对它的引用,我相信我将无法再访问它,因为它超出了范围。正确的吗?

正确,析构函数超出范围时将被调用。

  

如果我只返回对象本身(不是对它的引用)怎么办?是否会调用复制构造函数?

可以调用复制构造函数和析构函数,但通常编译器将执行返回值优化,不会进行复制,析构或移动。

要了解移动构造函数,请阅读移动语义和右值引用。

答案 1 :(得分:0)

如果我在堆栈上声明了一个对象,并且我返回对它的引用,我相信我将无法再访问它,因为它超出了范围。正确的吗?

  

正确,许多编译器也会给你警告。

如果我只返回对象本身(不是对它的引用)怎么办?是否会调用复制构造函数?

  

它会调用复制构造函数。标准的std :: array没有   std :: move构造函数在内部定义它使用堆栈内存。   因此将调用复制构造函数。

在哪些情况下会调用析构函数?

在这两种情况下,析构函数都会被调用。它只是在移动构造函数之后,我们将所有指针/处理移动到其他对象,因此对象状态将是空的(但是一致)。

答案 2 :(得分:0)

编译器将尝试优化此类函数以消除复制操作。生成的代码将表现为对象是在函数将以适当的生命周期返回的位置创建的。参考here。 这取决于编译器,以及构造和使用点处代码本身的结构。优化也可能无法实现,在这种情况下,如果可用,您可能会调用复制或移动构造函数。

如果编译器优化了该函数,那么当使用点处的对象超出最近的块范围时,将调用析构函数。

如果没有优化,那么对象将被复制到另一个使用点(一次调用复制/移动构造函数),然后函数中的对象将被销毁(如果被复制),最后是析构函数复制/移动的对象在函数返回时离开最近的块范围时将被调用(使用点)。

但是,如果从函数返回一个临时函数,那么你将返回一个引用或指向被破坏内存的指针,因为你的临时函数会在函数返回时超出范围并被销毁。