I'm working on a gui app with cpp and gtkmm3. In this app, some widgets require the singleton pattern to implement such as window (because i want just one window in all over the app) this is my header file:
class MyWindow : public Gtk::ApplicationWindow {
public:
MyWindow(BaseObjectType *pWindow, Glib::RefPtr<Gtk::Builder> builder);
~MyWindow();
MyWindow(MyWindow const&) = delete;
void operator=(MyWindow const&) = delete;
static MyWindow* getInstance();
private:
MyWindow();
};
and source file is :
MyWindow::MyWindow(){}
MyWindow::MyWindow(BaseObjectType *pWindow, Glib::RefPtr<Gtk::Builder> refBuilder)
: Gtk::ApplicationWindow(pWindow),
builder(refBuilder) {
}
MyWindow::~MyWindow() {}
MyWindow *MyWindow::getInstance() {
static MyWindow *window;
return window;
}
my question is: Is there a more appropriate and reasonable pattern instead singleton pattern ? Is using this pattern suitable for the interface widgets and gui app ?
CodePudding user response:
The major problem with the Singleton design pattern is that it gives you:
- a single instance AND
- global access.
The single instance aspect of the singleton is what people usually are looking for (like in your case), but not global access.
The usual "alternative" to this is to declare a MyWindow
instance and then inject it to anyone who needs it. This is known as dependency injection. So you have something like:
void DoSomeThingOnWindow(MyWindow& p_window)
{
p_window.DoSomething();
}
// At the beginning:
MyWindow window;
// Everywhere else:
DoSomeThingWithTheWindow(window);
instead of:
void DoSomeThingOnWindow()
{
// Global access:
MyWindow* window = MyWindow::getInstance();
window->DoSomething();
}
// Everywhere:
DoSomeThingWithTheWindow();
The "bad" side of dependency injection over a singleton is that it will not enforce the single instance. However, if you use it everywhere and carefully, you can pass a single instance all around and not have global access, which will have so much more benefits.