简体   繁体   中英

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

For example:

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_;
};

The C++ Standard defines that for an object of type D , its lifetime ends when the destructor ~D() call starts .

Can we interpret this to mean that modifying the object inside the destructor, as in (1), results in undefined behavior?

If so, does the same apply if we modify the base class subobject of D , as in (2)?

Neither access is undefined, they're both perfectly okay.

While you're right that the lifetime ends when the destructor starts, you can still use the object in limited ways, defined as:

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] .

and [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.

The above clearly states that only after the destructor finishes you can't touch members of that object.

None of the examples you've shown are undefined behavior. They are perfectly defined.

The class instance exists until the destructor returns. The object's members get destroyed not before the destructor gets called, but after it returns. As such, modifying the members of the class, in the destructor, is completely kosher. And the superclass does not get destroyed until the subclass gets completely destroyed, so modifying the superclass's members is perfectly fine, too.

Very generally speaking, an object gets destroyed by the following process:

  1. The destructor gets called.
  2. The class members get destroyed, in reverse order of their initial construction.
  3. Steps 1 and 2 are repeated for the object's superclasses.

(I am ignoring virtual inheritance, for simplicity, and it's not relevant here).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM