【问题标题】:Does C++ call destructors for global and class static variables?C++ 是否为全局和类静态变量调用析构函数?
【发布时间】:2011-01-13 08:38:29
【问题描述】:

从我的示例程序中,看起来它在这两种情况下都调用了析构函数。它在什么时候调用全局变量和类静态变量的析构函数,因为它们应该分配在程序堆栈的数据部分?

【问题讨论】:

    标签: c++ global-variables destructor


    【解决方案1】:

    来自 C++03 标准的第 3.6.3 节:

    静态存储持续时间(在块范围或命名空间范围声明)的已初始化对象的析构函数 (12.4) 作为从 main 返回的结果和调用 exit (18.3) 的结果而被调用。这些对象的销毁顺序与其构造函数完成或动态初始化完成的相反顺序。如果对象是静态初始化的,则对象的销毁顺序与动态初始化对象的顺序相同。对于数组或类类型的对象,该对象的所有子对象都会在构造子对象期间初始化的具有静态存储持续时间的任何本地对象被销毁之前被销毁。

    此外,§ 9.4.2 7 规定:

    静态数据成员的初始化和销毁​​与非本地对象(3.6.2、3.6.3)完全相同。

    但是,如果析构函数没有可观察的行为,则它可能不会被调用。 Terry Mahaffey 在他的answer to "Is a C++ destructor guaranteed not to be called until the end of the block?" 中详细说明了这一点。

    【讨论】:

    • 作为观察:Visual C++ 2010 似乎忽略了这个标准(以及其他标准)。我无法在测试析构函数中捕获断点。见:pastebin.com/sCMFYhzZ
    • @progician:析构函数有可观察的行为吗? VC++ '10 可能被允许省略析构函数调用。尝试打印提示然后读取输入,或打开文件并在析构函数中写入。
    • ...当然,如果 VC++ 忽略了标准,我也不会太惊讶。
    • FWIW 我在使用 VS2008SP1 时遇到了这个问题。添加了一个printf,仍然没有功能。这是有问题的,因为我试图根据他们的文档调用 curl_global_cleanup()。
    【解决方案2】:

    “主要”之后的某个地方

    (您无法知道或依赖它们被调用的确切顺序)

    【讨论】:

    • 它发生在 之前 std::cout 被破坏。 IE。你可以在那里打印东西。
    • @MSalters 我认为这只是您的特定实现的细节和/或您声明对象相对于cout 或调用其构造函数的第一个调用的顺序(例如operator<<()) .我怀疑它是有保证的,在这种情况下,我会在这个答案中再次强调“不能依赖”。
    • @underscore_d:不,这绝对是一种保证。这是可能的,因为标准库对于实现来说是特殊的/已知的。
    • @MSalters 谢谢,您的评论为我指明了方向:stackoverflow.com/questions/8784892/… 最佳答案和 Jerry Coffin 对第二个答案的评论似乎是最相关的位。这是我今天学到的新东西!
    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 2015-06-12
    • 2011-04-27
    • 2016-11-25
    • 2017-06-05
    • 1970-01-01
    • 2021-08-19
    • 2016-07-26
    相关资源
    最近更新 更多