C++ 修改析构函数中的类成员对象是否会导致未定义的行为?
例如:C++ 修改析构函数中的类成员对象是否会导致未定义的行为?,c++,language-lawyer,destructor,undefined-behavior,lifetime,C++,Language Lawyer,Destructor,Undefined Behavior,Lifetime,例如: struct B { int b_; }; struct D : B { ~D() { // D object's lifetime ends here d_ = 0; // (1) undefined behavior? b_ = 0; // (2) undefined behavior also? } int d_; }; 对于类型为D的对象,当析构函数~D()调用启动时,其生存期结束 我们是否可以将其解释为修改析
struct B { int b_; };
struct D : B
{
~D()
{ // D object's lifetime ends here
d_ = 0; // (1) undefined behavior?
b_ = 0; // (2) undefined behavior also?
}
int d_;
};
对于类型为D
的对象,当析构函数~D()
调用启动时,其生存期结束
我们是否可以将其解释为修改析构函数内的对象(如(1)中所述)会导致未定义的行为
如果是这样,那么如果我们修改
D
的基类子对象(如(2)中所示),是否也适用同样的情况?您所展示的示例都不是未定义的行为。它们的定义是完美的
在析构函数返回之前,类实例一直存在。对象的成员不是在调用析构函数之前被销毁,而是在它返回之后被销毁。因此,在析构函数中修改类的成员是完全合乎礼仪的。在子类完全销毁之前,超类不会被销毁,因此修改超类的成员也很好
一般来说,对象会通过以下过程被销毁:
(为了简单起见,我忽略了虚拟继承,它在这里不相关)。访问都不是未定义的,它们都很好 虽然生命周期在析构函数启动时结束是正确的,但您仍然可以以有限的方式使用对象,定义如下: N4140§3.8[基本寿命]/6 同样,在一个 对象已启动,但在对象将占用的存储之后 已分配,或在对象的生存期结束后 在重新使用或释放对象占用的存储之前, 引用原始对象的任何glvalue都可以使用,但只能在 有限的方式。有关正在构建或销毁的对象,请参见 [class.cdtor] 和[class.cdtor]: N4140§12.7[类别cdtor]/1 对于具有非平凡析构函数的对象,引用 析构函数后对象的非静态成员或基类 完成执行会导致未定义的行为
上面清楚地指出,只有在析构函数完成后,您才能接触该对象的成员。
当析构函数~D()调用开始时,它的生存期结束。
否!生命结束后!构造函数结束了@克劳斯,这是不对的。当析构函数调用时,生存期结束starts@krzaq:我可以使用析构函数的所有数据成员执行析构函数中的所有操作。在到达结束“}”之前,它没有任何问题。那么,为什么您认为生命周期在析构函数开始时结束呢?代码基本上是好的,原因与struct X{int a;X(){a=0;}代码>很好:当对象分别在构造函数或析构函数中进行构造或销毁时,可以引用成员。@LeoHeinsaar:KerrekSB的示例显示赋值,而不是初始化。看起来很彻底,谢谢。我将重新措辞这个问题,使之成为一个问题,以免混淆其他观众。