C++:对话框的单个实例?

C++: Single instance of a dialog?

我有一个对话框我想只存在一次,作为两个不同的 类(MainFrame,可以直接打开它,Wizard,它可以使用从向导本身引入的设置打开它)必须在任何给定时间访问它。理想情况下,我希望用户能够使用向导打开对话框,填写所有内容,然后关闭它。如果他们需要更改设置,他们应该能够使用 MainFrame 打开它并在那里进行编辑。

我目前实现它的方式有两个不同的对话框实例。向导后从MainFrame打开的话,Mainframe会有默认值,而Wizard也可以用向导的值打开。

我尝试按照 this 实施单例设计模式,但尝试打开向导或对话框本身会导致出现 xC0000005 错误。

MainFrame 可以访问向导和对话框 header,并且对话框可以访问向导 header 以实现将数据从向导传递到对话框的功能(使用对话框 forward-declared 在向导的 header).

我真的不确定如何推进这项工作,但我们非常感谢您的帮助。如有必要,我可以提供我的实现代码。

编辑:在链接 URL 之外没有做太多事情,但如果有任何区别的话,它是在 wxWidgets 上开发的。这是相关代码。

Dialog.h

#include "Wizard.h"
class Dialog
{
private:
    Dialog() {}
    Dialog(Dialog const& copy) {}
    Dialog& operator=(Dialog const& copy) {}

    static Dialog* instance;

//many functions and variables

public:
    Dialog(wxWindow* parent) //more fields, generated by wxFormBuilder
    ~Dialog();

    Wizard* wizard;
    void SetRelative(Wizard* inWizard);

    static Dialog* GetInstance()
    {
        instance = new Dialog(NULL);
        return instance;
    }
};
Dialog.cpp

#include "Dialog.h"

Dialog* Dialog::instance = 0;

Dialog::Dialog(wxWindow parent, etc.)
{
    //lots of stuff
}

//event handlers, helper functions

void Dialog::SetRelative(Wizard* inWizard)
{
    this->Wizard = inWizard
}
Wizard.h

class Dialog;

class Wizard
{
public:
    Dialog* dialog;
}
Wizard.cpp

#include "WizardSetup.h"
#include "WizardDialog.h"

Wizard::Wizard(wxWindow* parent, etc.)
{
//bunch of stuff
    dialog->GetInstance()
    dialog->SetRelative(this) <--------- hangs at this statement
}
MainFrame.cpp

#include "Dialog.h"
#include "Wizard.h"

class MainFrame: public wxFrame
{
protected:
    Dialog* m_dialog;
    Wizard* m_wizard;

etc.
}
MainFrame.cpp
#include "MainFrame.h"

MainFrame::MainFrame(wxWindow* parent, etc.)
{
//stuff here

m_dialog->GetInstance();
}

void MainFrame::menuDialogOnMenuSelection( wxCommandEvent& event)
{
    m_dialog->Show(); <-------- hangs here
}

此代码的三个(即时)问题:

  1. 您的 Dialog::Dialog(WxWindow*) 构造函数是 public,它发送有关单例对象性质的混合信号。虽然不直接对崩溃或挂起负责,但当 The Next Guy(这可能一个月后成为你)尝试维护此代码。

  2. 您没有检查 Dialog::GetInstance() 函数中是否存在已实例化的 Dialog。你应该

static Dialog* GetInstance()
{
    if (instance == nullptr) instance = new Dialog(nullptr);
    return instance;
}
  1. 您没有为各种 Dialog* 成员变量(例如 Wizard::dialogMainFrame::m_dialog)分配单例 Dialog 的地址。一定要这样做:
// (in the Wizard constructor for example)
dialog = Dialog::GetInstance();

附录说明:我认为值得一提的是单例模式通常称为 anti 模式。我不够聪明,无法理解为什么。据推测,它往往会导致一些不良的编码习惯,而且有时处理起来肯定很麻烦,但是,嘿,不管怎样都能完成工作。请记住,根据某些人的说法,它不一定是完成这项工作的最佳工具。