| Singletonパターンでモードレスダイアログを作成する |
// Singletonクラスの定義
class Singleton{
public:
static Singleton* Instance(); // インスタンスの生成を行う静的メンバ関数
protected:
singleton(); // デフォルトコンストラクタはprotectedにする
private:
static Singleton* _instance; // 生成されたインスタンスへのポインタを持つ静的メンバ変数
};
// 静的メンバ変数の初期化
Singleton* Singleton::_instance = NULL;
// 静的メンバ関数の実装
Singleton* Singleton::Instance(){
if(_instance == NULL){
_instance = new Singleton;
}
return _instance;
}
上記はSingletonクラスの簡単な定義である。デフォルトコンストラクタがprotected指定されているので、通常の方法ではインスタンスを生成することはできない。静的メンバ関数であるSingleton::Instance()を呼び出すことで生成可能である。
Singleton single; // エラー
Singleton* pSingle = new Singleton; // エラー
Singleton::Instance(); // 正しい
ここでSingleton::Instance()の実装に注目してほしい。この中ではまず静的メンバ変数_instanceがNULLかどうか判定している。この変数は生成されたインスタンスへのポインタを持つ。つまり、この変数がNULLでないときはすでにインスタンスが生成されているので、if文の中にある処理が呼ばれない。すなわちデフォルトコンストラクタは呼ばれることはなく、これ以上インスタンスが生成されることはないわけである。
// クラスの定義 ---------------------------
class CSingletonDialog : public CDialog
{
// コンストラクション
public:
static CSingletonDialog* Instance(); // インスタンスの生成を行う静的メンバ関数
protected:
CSingletonDialog(CWnd* pParent = NULL); // デフォルトコンストラクタはprotectedにする!
……
private:
static CSingletonDialog* m_Instance; // 生成されたインスタンスへのポインタを持つ静的メンバ変数
};
// クラスの実装 ---------------------------
// 静的メンバ変数の初期化
CSingletonDialog* CSingletonDialog::m_Instance = NULL;
// 静的メンバ関数の実装
CSingletonDialog* CSingletonDialog::Instance()
{
if( m_Instance == NULL ) {
m_Instance = new CSingletonDialog;
}
return m_Instance;
}
// デフォルトコンストラクタの実装
CSingletonDialog::CSingletonDialog(CWnd* pParent /*=NULL*/)
: CDialog(CSingletonDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CSingletonDialog)
// メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
//}}AFX_DATA_INIT
Create(IDD_DIALOG_MODERESS);
}
// OnCancel関数
void CSingletonDialog::OnCancel()
{
// TODO: この位置に特別な後処理を追加してください。
CDialog::OnCancel();
delete m_Instance;
m_Instance = NULL;
}
先に記したSingletonパターンの定義とほとんど変わらない。追加されたのはデフォルトコンストラクタ内でCreate関数を呼び出してモードレスダイアログを生成する処理と、OnCancel関数内でダイアログの破棄を行う処理である。もちろん、OKボタンでダイアログを閉じる場合はOnOK関数にも同じ処理を施さなければならない。