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
}
此代码的三个(即时)问题:
您的 Dialog::Dialog(WxWindow*)
构造函数是 public,它发送有关单例对象性质的混合信号。虽然不直接对崩溃或挂起负责,但当 The Next Guy(这可能一个月后成为你)尝试维护此代码。
您没有检查 Dialog::GetInstance()
函数中是否存在已实例化的 Dialog
。你应该
static Dialog* GetInstance()
{
if (instance == nullptr) instance = new Dialog(nullptr);
return instance;
}
- 您没有为各种
Dialog*
成员变量(例如 Wizard::dialog
和 MainFrame::m_dialog
)分配单例 Dialog
的地址。一定要这样做:
// (in the Wizard constructor for example)
dialog = Dialog::GetInstance();
附录说明:我认为值得一提的是单例模式通常称为 anti 模式。我不够聪明,无法理解为什么。据推测,它往往会导致一些不良的编码习惯,而且有时处理起来肯定很麻烦,但是,嘿,不管怎样都能完成工作。请记住,根据某些人的说法,它不一定是完成这项工作的最佳工具。
我有一个对话框我想只存在一次,作为两个不同的 类(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
}
此代码的三个(即时)问题:
您的
Dialog::Dialog(WxWindow*)
构造函数是 public,它发送有关单例对象性质的混合信号。虽然不直接对崩溃或挂起负责,但当 The Next Guy(这可能一个月后成为你)尝试维护此代码。您没有检查
Dialog::GetInstance()
函数中是否存在已实例化的Dialog
。你应该
static Dialog* GetInstance()
{
if (instance == nullptr) instance = new Dialog(nullptr);
return instance;
}
- 您没有为各种
Dialog*
成员变量(例如Wizard::dialog
和MainFrame::m_dialog
)分配单例Dialog
的地址。一定要这样做:
// (in the Wizard constructor for example)
dialog = Dialog::GetInstance();
附录说明:我认为值得一提的是单例模式通常称为 anti 模式。我不够聪明,无法理解为什么。据推测,它往往会导致一些不良的编码习惯,而且有时处理起来肯定很麻烦,但是,嘿,不管怎样都能完成工作。请记住,根据某些人的说法,它不一定是完成这项工作的最佳工具。