c++polymorphism

Can I call method in each base recursively without manually typing base::Method()?


The question

I am facing a problem. I have a class A that has a base B (is polymorphic). In B class is method Print(), which is virtual. In A class is also Print(). virtual. Lets say I am given an A type object (or pointer), stored in B variable

B * object = new A(); 

And by calling

object->Print();

It calls the method in A class, but I also want it to call method in B class. Technically I want to call the method for each child until I reach class that has no child This can be done as follows:

Example

class A
{
   public:
      virtual void Print() const override
      {
          cout << "A" << endl;
      }
};
class B : public A
{
   public:
      virtual void Print() const override
      {
         cout << "B" << endl;
         A::Print();     // I do not want to call it here...
      }
};

The problem is that I do want not to be forced to call the

A::Print();

Why

Yes, you might be asking, what is the deal... I have very long inheritance chain. (lets say that there are like 15 - 20 classes in the inheritance chain). In a game, each one does some little thing.

Lets say

 class GameObject
    {
       public:
          virtual void Update() const
          {
              //updates position, recounts it towards screen
          }
    };
    class Character : public GameObject
    {
       public:
          virtual void Update() const override
          {
             // Updates lives, movement
          }
    };
    class Warrior : public Character
    {
       public:
          virtual void Update() const override
          {
             // Updates armor, specific stuff
          }
    };

Now this example is very simplified. Problem is, that if I forget to add a call base::Update() Then I am wondering why does it not work. Looking for such a mistake is hard. I mean, if there any way around it?

Thank you very much indeed for any responses.


Solution

  • If indeed every class must call the base function, one way to ensure the functionality is enforced is to use the template pattern.

    class GameObject
    {
    
       public:
          void Updater()
          {
             Update();  // this is a virtual call
             GameObject::Update(); // now call base 
          }
    
          virtual void Update() const
          {
          }
    };
    
    class Character : public GameObject
    {
       public:
          virtual void Update() const override
          {
             // Updates lives, movement
          }
    };
    
    class Warrior : public Character
    {
       public:
          virtual void Update() const override
          {
             // Updates armor, specific stuff
          }
    };
    
    class Character : public GameObject
    {
       public:
          virtual void Update() const override
          {
             // Updates lives, movement
          }
    };
    
    class Warrior : public Character
    {
       public:
          virtual void Update() const override
          {
             // Updates armor, specific stuff
          }
    };
    

    Then always call YourObject::Updater(); instead of YourObject::Update(). The Updater function will call your object's Update function, and then return and call the base class Update.