【问题标题】:what is the destruction order between global object and static variable? [duplicate]全局对象和静态变量之间的破坏顺序是什么? [复制]
【发布时间】:2012-12-31 01:13:52
【问题描述】:

可能重复:
Object destruction in C++

假设我们有两个类,一个叫Array,另一个叫MessageOnExit

假设Array 类有一个名为counter 的静态数据成员。

以下是课程:

class Array {
public:
    static int counter;
    Array(){counter++;}
    ~Array(){counter--;}
};

class MessageOnExit {
public:
    ~MessageOnExit(){cout << Array::counter;}
};

以下是使用这些类的“main”

// static variable definition
int Array::counter;
// global object definition
MessageOnExit message;

void main() {
    Array a1, a2;
    Array a3(a1);
}

前两个声明将 counter 更改为 2,随后两次调用 Empty/Default 构造函数 第三个声明不会更改counter,因为将调用默认复制构造函数。

现在,当main 执行完成时,静态成员counter 的值将是-1 的析构函数调用(在a1、a2 和a3 被销毁之后),然后message 析构函数将被调用,打印这个值 (-1)。

我的问题是,当调用 message 析构函数时,我们如何知道静态成员 counter 仍然存在并且可用。

另外,如果我改变静态/全局对象/变量的定义顺序,即messagecounter之前定义,值仍然是-1

总而言之,无论我做什么更改,当程序终止消息析构函数成功访问静态成员counter 时,我不明白为什么会这样。据我了解,如果首先定义全局对象 message,则其析构函数将被最后调用,因此 counter 值将不可用于其析构函数。

提前致谢! 伙计

【问题讨论】:

  • 看看thisthisthis
  • 在对象被销毁后使用它不是一个诊断错误,它的行为未定义,所以任何事情都可能发生——代码可能有一天会正常工作,但第二天会中断。
  • 我删除了所有粗体文本,因为它具有强调文本部分不应该的效果。我要么删除它,要么将它们更改为代码引号。如果您认为确实需要,您可以在某些地方重新添加粗体。
  • 重新打开这个问题。这里重要的一点是,带有普通析构函数的静态对象永远不会被销毁。见阿舍普勒的回答。其他问题的答案中没有明确说明,

标签: c++


【解决方案1】:

标准第 3.8 节说:

T 类型对象的生命周期结束于:

  • 如果 T 是具有非平凡析构函数 (12.4) 的类类型,则析构函数调用开始,或者

  • 对象占用的存储空间被重用或释放。

现在int 不是类类型,并且由于Array::counter 具有静态存储持续时间,因此它的存储永远不会被释放。所以Array::counter 的生命周期永远不会结束,你可以从任何你想要的析构函数中安全地访问它!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    相关资源
    最近更新 更多