Search code examples
c++classinheritancechildren

In C++, how do I determine if a class is the last class/child in an inheritance chain? ie on the opposite end of the base class


I'm having problems wording this question concisely, but basically there is a function in a class that may be the last class in an inheritance chain, or it may not be. Inside this function, IF the class-level function is the last in an inheritance chain, a 2nd function will be called. It is much easier to show what I'm talking about than to explain it, so:

Lets say that I have class Z.

Z derives from Y, which derives from X, which derives from W.

All of the classes have a virtual function called Execute().

Z.Execute() requires that Y.Execute() be finished, which requires that X.Execute() be finished, which requires that W.Execute() be finished.

As such, Z's Execute() function looks like:

void Z::Execute(void)
{
   Y::Execute();

   // do Z's stuff!
   return;
}

Similarly, Y's Execute() function looks like:

void Y::Execute(void)
{
   X::Execute();

   // do Y's stuff!
   return;
}

And so on down the chain of inheritance.

But Y, nor X, nor W are abstract, and so each can be instantiated, and may or may not be the last class in the inheritance chain.

Here's what I need to know. The last Execute() needs to call DoThisAtEndOfExecute(). DoThisAtEndOfExecute() needs to be called internal to the classes, ie. it will not be public.

So it can't be in X's Execute(), because if the class is a Y, it'll be called too early. It can't be in Y's Execute(), because the class may be a Z. It can't be in Z's Execute() because if the class is an Y, X, or W, the function will never get called.

So is there any way for a class to tell whether it has been inherited FROM? Basically, the equivalent to:

if (!IAmTheParentOfSomething)
   DoThisAtEndOfExecute();

How is this ever done? I concede that an easier way would be for the function that contains the class to do:

X.Execute();
X.DoThisAtEndOfExecute();

But that isn't really an option for this code.


Solution

  • I think what you want can be achieved if you split Execute into a nonvirtual part and a virtual part. The former will run the latter, then invoke DoThisAtEndOfExecute. Like this:

    class X
    {
    public:
        void Execute()
        {
            ExecuteImpl(); //That one's virtual, the derived classes override it
            DoThisAtEndOfExecute();
        }
    
    protected:
        virtual void ExecuteImpl()
        {
            //Whatever was in the legacy Execute
        }
    }
    

    Y and Z override ExecuteImpl() and call the base. This way, DoThisAtEndOfExecute() runs after the most derived version of ExecuteImpl() is finished, without any knowledge of the actual class.