Reason reqd for the order of destructor call .?

2019-02-19 04:54发布

问题:

As I have read in certain forums,when derived class object is created base class members and methods are allocated space in the memory but there is no specific base class object.

Now as the derived class object goes out of scope , why derived class destructor is called first.What is the constraint of the compiler where derived class destructor cannot be called after base class destructor..?

Please correct me in case I have built a wrong understanding..Thanks in advance

回答1:

When a derived class object is created, there is a specific base-class object (sub-object, really). I.e., when you create a derived object, a base class ctor is used to initialize the base class subj-object within the derived object, and only after that completes does the derived class ctor get to do its thing, initialing any members added in the derived class, etc.

Since it's built from base to derived, it's torn down from derived to base. When the derived dtor ends execution, there should still be a perfectly valid base object waiting for the base dtor to destroy it. If you tried to destroy the base sub-object first, however, when you ran the derived dtor, you'd no longer have a valid derived object for the derived dtor to destroy.



回答2:

The derived class destructor may access base class members, so it needs the base class object to be in a valid state.



回答3:

One the class X destructor is called, the object it was called on ceases to be an object of type X.

Suppose you have a class Y which inherits from X, and a class Z that inherits from Y. By the principles of object-oriented inheritance, every Y is an X. And every Z is a Y and an X.

Look at what happens when deleting an object of type Z if the destructors are called from most-derived to base:

  • First the Z destructor executes. The object stops being a Z and reverts to being only a Y.

  • Then the Y destructor executes. The object stops being a Y and reverts to being only an X.

  • Then the X destructor executes. The object stops being an X, and is now nothing at all (completely destroyed).

Now consider what would happen if instead the base destructor was called first:

  • First the X destructor executes. The object stops being an X.

Now what is the object? It's not an X, but it can't be a Y either since a Y is an X. It can't be a Z since a Z is an X too! The object has no clearly-defined type at this point, and so invoking another method on it, even another destructor, would lead to impossible-to-define behavior.

In more concrete terms: It's entirely possible that the Z destructor or the Y destructor needs to access something that is defined in the X class. So the X destructor must run last. Note that there's no problem in the other direction since the base class X can't access anything in its derived classes.



回答4:

There is a small trick you can use: The destructors of the members of an derived class are called after the whole stack of destructors was called.

I have retested now with a member of type std::map and it appears not to be true. SORRY.