1

I want to call update for each derived object without a loop, this is the code that produces the loop from method "update()". How to solve it the right way?

#include <iostream>

class Base {
public:
  virtual void update(Base *b1) {
    this->updateInternal();
  }

  virtual void updateInternal() = 0;
};

class DerivedClass1 : public virtual Base 
{
public:
  void updateInternal() override {
    std::cout << "DerivedClass1::updateInternal()" << std::endl;
  }
};

class DerivedClass2 : public virtual Base 
{
public:
  void updateInternal() override {
    std::cout << "DerivedClass2::updateInternal()" << std::endl;
  }
};

class DerivedClassSuper : public virtual DerivedClass1, public virtual DerivedClass2
{
  void updateInternal() override {
    std::cout << "DerivedClassSuper::updateInternal()" << std::endl; // <-- This is the first to be called, LOOP
    std::cout << "DerivedClass1::update(this)" << std::endl; // <-- This is the second to be called
    DerivedClass1::update(this); // <-- This is the third to be called, LOOP
    std::cout << "DerivedClass2::update(this)" << std::endl; // <-- This is the fourth to be called, but never reached
    DerivedClass2::update(this);
  }
};

int main() {
  DerivedClassSuper d;
  d.update(&d); // <-- Start the chain of updates
  /*
    DerivedClassSuper::updateInternal()
    DerivedClass1::update(this)
    DerivedClassSuper::updateInternal()
    DerivedClass1::update(this)
    DerivedClassSuper::updateInternal()
    DerivedClass1::update(this)
    DerivedClassSuper::updateInternal()
    DerivedClass1::update(this)
    DerivedClassSuper::updateInternal()
    DerivedClass1::update(this)
  */
  return 0;
}

The problem is that this will produce a loop in update() because updateInternal() is called. This is the output of the loop after calling update:

DerivedClassSuper::updateInternal()

DerivedClass1::update(this)

DerivedClassSuper::updateInternal()

DerivedClass1::update(this)

DerivedClassSuper::updateInternal()

DerivedClass1::update(this)

DerivedClassSuper::updateInternal()

DerivedClass1::update(this)

DerivedClassSuper::updateInternal()

DerivedClass1::update(this)

What is the best and nicest solution for this problem?

Thank you!

3
  • The virtual inheritance in DerivedClassSuper of DerivedClass1 and DerivedClass2 doesn't do anything, since neither of those bases occurs more than once. Commented Sep 10, 2024 at 21:08
  • Besides the issue you are experiencing, I fail to understand why you thought you needed to declare virtual void update(Base *b1) instead of void update(). update is not overridden anywhere so it does not need to be virtual and it does not use the b1 parameter (which you forced to be the same as this everywhere you call the method). Commented Sep 12, 2024 at 13:57
  • Hi, thank you. I know that virtual is not needed. But there should be the opportunity to overwrite. Commented Sep 12, 2024 at 14:24

1 Answer 1

1

You currently call Base::update in DerivedClassSuper::updateInternal which in turn calls updateInternal in the most derived class (DerivedClassSuper) which again calls Base::update ... and there you got the endless recursion.

Instead, call your base classes' updateInternal():

class DerivedClassSuper : public DerivedClass1, public DerivedClass2 {
    void updateInternal() override {
        std::cout << "DerivedClassSuper::updateInternal()\n";
        std::cout << "DerivedClass1::updateInternal()\n";
        DerivedClass1::updateInternal();
        std::cout << "DerivedClass2::updateInternal()\n";
        DerivedClass2::updateInternal();
    }
};

Demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.