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