I'm developing an UI application where I ran into an issue with a cyclic dependency. Here is the simplified code, to explain the problem.
#include <list>
class UiStyle;
UiStyle* CreateStyle();
class UiWindow {
public:
virtual void Draw() = 0;
};
class UiMenu : public UiWindow {
public:
void Draw() override {
// Some UI drawing
// How should I implement changing style from here?
}
};
class UiApplication {
public:
void Draw() {
for (UiWindow* window : this->windows)
window->Draw();
}
protected:
void SetStyle(UiStyle *style);
void AddWindow(UiWindow* window) {
this->windows.push_back(window);
}
private:
std::list<UiWindow*> windows;
};
class UiMainApplication : public UiApplication {
public:
void Initialize() {
this->SetStyle(CreateStyle());
this->AddWindow(new UiMenu());
}
};
Explanation:
- UiStyle - application style class.
- CreateStyle - method that creates some UI style.
- UiWindow - interface of an UI window (not to be changed)
- UiMenu - some implemented UI window from where I need to change a style.
- UiApplication - base application class that provides managing windows, styles, etc. (not to be changed)
- UiMainApplication - implemented application that adds real windows, sets real style.
The problem I face is about changing the application style from inside UiMenu
. How can UiMenu
call UiApplication::SetStyle
?
Of course, I could pass UiMainApplication
pointer to UiMenu
, then create public method UiMainApplication::SetStyle
that will allow to call UiApplication::SetStyle
, and call UiMainApplication::SetStyle
from UiMenu
. But, as far as I know, it's bad practice, to have a bidirectional reference, like A -> B and B -> A. In my case, UiMainApplication
would refer to UiMenu
and UiMenu
refer to UiMenuApplication
.
Hence I think it's not the best way to implement it.
Hope for your help! I will be glad to any suggestions!