【问题标题】:Singleton pattern with gtk3 and gtkmm带有 gtk3 和 gtkmm 的单例模式
【发布时间】:2022-01-09 06:15:18
【问题描述】:

我正在使用 cpp 和 gtkmm3 开发一个 gui 应用程序。 在这个应用程序中,一些小部件需要单例模式来实现,例如窗口(因为我想要整个应用程序中只有一个窗口) 这是我的头文件:

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();

};

源文件是:



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

我的问题是: 有没有更合适和合理的模式而不是单例模式? 使用这种模式是否适用于界面小部件和 gui 应用程序?

【问题讨论】:

  • 很多时候单例可以被非单例替换。它不是一种模式,因为它只是一个类,就像您创建一个实例的任何其他类一样
  • 顺便说一句,你的MyWindow 有点坏了。 getInstance 不返回实例,而只是返回一个无处指向且无法实际创建实例的指针
  • 是的。但是在这种情况下,我有一个类需要在其他几个类中使用。
  • 这只是一个例子。我正在使用 Glade 和 Gtk::Builder 它可以正常工作。
  • 问题是关于意见的,因此是题外话。单例是伪装的全局变量,关于为什么应该避免使用全局变量,您可以阅读例如stackoverflow.com/q/19158339/4117728。恕我直言,记录器是全局/单例的有效案例,因为无论该代码实际处理什么,您都需要它在所有代码中,窗口不是那个

标签: c++ qt user-interface gtk3 gtkmm


【解决方案1】:

单例设计模式的主要问题是它给你:

  1. 单个实例 AND
  2. 全球访问。

单例的单实例方面是人们通常正在寻找的(就像你的情况一样),但不是全局访问。

通常的“替代方案”是声明一个MyWindow 实例,然后注入它给任何需要它的人。这被称为dependency injection。所以你有类似的东西:

void DoSomeThingOnWindow(MyWindow& p_window)
{
    p_window.DoSomething();
}

// At the beginning:
MyWindow window;

// Everywhere else:
DoSomeThingWithTheWindow(window);

代替:

void DoSomeThingOnWindow()
{
    // Global access:
    MyWindow* window = MyWindow::getInstance();
    window->DoSomething();
}

// Everywhere:
DoSomeThingWithTheWindow();

依赖注入对单例的“坏”方面是它不会强制单个实例。但是,如果您在任何地方都小心使用它,您可以到处传递单个实例,而没有全局访问权限,这将带来更多好处。

【讨论】:

  • 你的意思是不是每个类都请求 MainWindow,而是为那个类提供它?
  • 是的,您提供它作为对您的单个实例的引用。这样做的效果之一是,现在从使用类中对窗口的依赖变得清晰了,这与隐藏它的单例相反。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-08
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多