在调用析构函数之前,对象的生命周期结束了吗?

时间:2011-12-23 01:48:20

标签: c++ destructor language-lawyer object-lifetime

我不明白这一点:

  

3.8 / 1“类型T的对象的生命周期在以下情况下结束: - 如果T是具有非平凡析构函数的类类型(12.4),则析构函数调用   开始,或 - 重用对象所占用的存储空间   释放“。

如果生命周期在析构函数启动之前结束,那是不是意味着在析构函数中访问成员是未定义的行为?

我也看到了这句话:

  

12.7“对于具有非平凡析构函数的对象,引用析构函数后对象的任何非静态成员或基类   完成执行导致未定义的行为。“

但它并不清楚析构函数中允许的内容。

4 个答案:

答案 0 :(得分:8)

  

如果生命周期在析构函数启动之前结束,那是不是意味着在析构函数中访问成员是未定义的行为?

希望不是:

来自N3242 构建和破坏[class.cdtor] / 3

  

要形成指向对象obj的直接非静态成员(或访问其值)的指针,obj的构造应该已经开始并且它的销毁不会完成,否则计算指针值(或访问成员值)会导致未定义的行为。

答案 1 :(得分:8)

对象的“生命周期”与对象的使用者相关,而不是对象本身。因此,一旦破坏开始,消费类不应该尝试访问对象的成员。

答案 2 :(得分:5)

不,没有问题:

成员对象在构造函数体运行之前变为活动状态,并且它们在析构函数完成之后保持活动状态。因此,您可以在构造函数和析构函数中引用成员对象。

对象本身直到它自己的构造函数完成后才会生效,并且它的析构函数一开始执行就会死掉。但这只是外界所关注的问题。构造函数和析构函数仍然可以引用成员对象。

答案 3 :(得分:1)

“终身”并不意味着。它是标准中精确定义的术语,具有多种含义,但它可能没有您想到的所有含义。在构造和销毁期间仍然可以使用成员,外部代码可以调用成员函数等等。

当然,客户端代码与析构函数同时调用成员函数有点奇怪,但并不是闻所未闻,当然也不会被语言禁止。特别是,std::condition_variable显式允许在对condition_variable::wait()进行未完成的调用时调用析构函数。它只禁止在析构函数启动后对wait()进行 new 调用。