我不明白这一点:
3.8 / 1“类型T的对象的生命周期在以下情况下结束: - 如果T是具有非平凡析构函数的类类型(12.4),则析构函数调用 开始,或 - 重用对象所占用的存储空间 释放“。
如果生命周期在析构函数启动之前结束,那是不是意味着在析构函数中访问成员是未定义的行为?
我也看到了这句话:
12.7“对于具有非平凡析构函数的对象,引用析构函数后对象的任何非静态成员或基类 完成执行导致未定义的行为。“
但它并不清楚析构函数中允许的内容。
答案 0 :(得分:8)
如果生命周期在析构函数启动之前结束,那是不是意味着在析构函数中访问成员是未定义的行为?
希望不是:
来自N3242 构建和破坏[class.cdtor] / 3
要形成指向对象obj的直接非静态成员(或访问其值)的指针,obj的构造应该已经开始并且它的销毁不会完成,否则计算指针值(或访问成员值)会导致未定义的行为。
答案 1 :(得分:8)
对象的“生命周期”与对象的使用者相关,而不是对象本身。因此,一旦破坏开始,消费类不应该尝试访问对象的成员。
答案 2 :(得分:5)
不,没有问题:
成员对象在构造函数体运行之前变为活动状态,并且它们在析构函数完成之后保持活动状态。因此,您可以在构造函数和析构函数中引用成员对象。
对象本身直到它自己的构造函数完成后才会生效,并且它的析构函数一开始执行就会死掉。但这只是外界所关注的问题。构造函数和析构函数仍然可以引用成员对象。
答案 3 :(得分:1)
“终身”并不意味着。它是标准中精确定义的术语,具有多种含义,但它可能没有您想到的所有含义。在构造和销毁期间仍然可以使用成员,外部代码可以调用成员函数等等。
当然,客户端代码与析构函数同时调用成员函数有点奇怪,但并不是闻所未闻,当然也不会被语言禁止。特别是,std::condition_variable
显式允许在对condition_variable::wait()
进行未完成的调用时调用析构函数。它只禁止在析构函数启动后对wait()
进行 new 调用。