【问题标题】:In what order are local scoped objects destructed?本地作用域对象的破坏顺序是什么?
【发布时间】:2013-08-12 16:46:31
【问题描述】:

foo 会在bar 之前、bar 之后被破坏,还是两者都不能保证?

myFunction()
{
    Foo foo = Foo();
    Bar bar = Bar();
    return;
}

【问题讨论】:

  • 在您的示例中未创建任何对象。相反,声明了两个函数,名为foobar。见"most vexing parse"
  • @IgorTandetnik 该死的你和你的正确性。 ;) 我已更新问题以反映意图。
  • 只是为了记录,C++ 没有函数作用域的对象。你所说的函​​数作用域只是局部作用域的一种特例。
  • @JamesKanze 感谢您提供信息。我已将问题更新为更准确。

标签: c++ scope destructor


【解决方案1】:

它们按照声明的相反顺序被销毁。在

{
 Foo foo = Foo();
 Bar bar = Bar();
}

首先构造foo,然后构造bar。超出范围时 - bar 首先被破坏,然后是 foo

【讨论】:

    【解决方案2】:

    函数的内存称为“堆栈”。和其他所有堆栈一样,你最后放的东西就是你要脱掉的第一件事。

    因此,实际上,当函数返回并且本地内存超出范围时,所有本地变量都以相反的顺序销毁。

    情况总是如此,您绝对可以依赖它(在同一个线程中)。

    【讨论】:

    • 这是很误导人的,因为临时对象也是放在栈上的,而且会在任何非临时对象之前被销毁(在完整表达式的末尾。
    • 不,它们将遵循相同的顺序。临时工通常是在以后穿上的,这就是为什么它们会更早地被销毁。
    • @user2032040 我认为,即使在更深的意义上,詹姆斯也是对的。编译器会以它认为合适的方式将局部变量放入堆栈,它不限于遵循您声明它们的顺序。构造函数和析构函数将以正确的顺序调用,但堆栈上的位置取决于编译器决定做什么。
    • @user2032040:是和不是。当您编写S s = std::string("Hello"); 时,编译器需要创建一个临时文件来保存std::string。它将代码转换为:std::string __tmp("Hello"); S s = __tmp; DESTROY(__tmp);。请注意 __tmp 的破坏是如何被称为 before s 的,即使它是构建的 before
    • @MatthieuM。是的。当临时变量参与局部变量的初始化时,几乎总是会出现这种情况。
    【解决方案3】:

    在继承中它是相反的顺序。在您的情况下,它的创建顺序相同。

     Foo f= new Foo();
     Bar b= new Bar();
    

    f 在 b 之前被销毁

    【讨论】:

    • 那甚至无法编译。 C++ != Java。
    猜你喜欢
    • 2012-12-15
    • 2016-08-27
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2020-06-12
    • 2011-01-18
    相关资源
    最近更新 更多