在析构函数中修改 class 成员对象是否会导致未定义的行为?

Does modifying class member objects in the destructor result in undefined behavior?

例如:

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类型的对象的C++ Standard defines,当析构函数~D()调用时,其生命周期结束开始.

我们能否将其解释为在析构函数中修改对象(如 (1) 中)会导致未定义的行为?

如果是这样,如果我们像 (2) 那样修改 D 的基 class 子对象,是否同样适用?

None 您展示的示例是未定义的行为。它们定义完美。

class 实例存在直到析构函数 returns。对象的成员不是在析构函数被调用之前被销毁,而是在它之后 returns。因此,在析构函数中修改 class 的成员是完全正确的。并且 superclass 在 subclass 完全销毁之前不会被销毁,因此修改 superclass 的成员也完全没问题。

一般来说,对象会被以下过程销毁:

  1. 析构函数被调用。
  2. class 成员被销毁,顺序与初始构造相反。
  3. 为对象的超classes 重复第 1 步和第 2 步。

(为了简单起见,我忽略了虚拟继承,这里不相关)。

访问权限都没有未定义,它们都很好。

虽然生命周期在析构函数启动时结束是正确的,但您仍然可以以有限的方式使用该对象,定义为:

N4140 § 3.8 [basic.life] / 6

Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor].

和[class.cdtor]:

N4140 § 12.7 [class.cdtor] /1

For an object with a non-trivial destructor, referring to any non-static member or base class of the object after the destructor finishes execution results in undefined behavior.

上面明确指出,只有在析构函数完成后,您才能接触该对象的成员。