【C++ベースの9】単例モード


1.作用
単一のモードの目的は、クラスが1つのインスタンスしかないことを保証することです.
2.原理
(1)プライベート静的ポインタ変数実装:クラスのプライベート静的ポインタ変数を使用してクラスの一意のインスタンスを指し、共通の静的メソッドでインスタンスを取得する.
(2)静的局所変数実装:クラスを指す静的局所変数を公有静的メソッドで定義し、静的局所変数を返す.
3.実現
3.1.プライベート静的ポインタ変数の実装
3.1.1.特長
A.クラスを指す唯一のプライベートメンバーポインタm_pInstance.
B.この一例を公有的に暴露する静的方法getInstanceがある.
C.コンストラクション関数はプライベートであり、他の場所からクラスインスタンスを作成しない.
D.単一クラスにおけるプライベート埋め込みクラスCGarboを定義し、その構造関数において単一クラスポインタを解放する.
E.CGarboクラスのインスタンスを静的メンバー変数として定義し、プログラム終了システムによってすべてのグローバル変数の特性が自動的に解析され、単一のポインタが自動的に解放される.
3.1.2.例
//Singleton1.h
#pragma once

class CSingleton1
{
public:

	static CSingleton1* getInstance()
	{
		if ( m_pInstance == NULL )
			m_pInstance = new CSingleton1();
		return m_pInstance;
	}

private:

	CSingleton1();

	static CSingleton1* m_pInstance;

	class CGarbo//             m_pInstance
	{
	public:
		~CGarbo()
		{
			if (CSingleton1::m_pInstance!=NULL)
			{
				delete CSingleton1::m_pInstance;
			}
		}
	};

	static CGarbo m_garbo;//    ,            

};
//Singleton1.cpp
#include "StdAfx.h"
#include "Singleton1.h"

CSingleton1* CSingleton1::m_pInstance=NULL;//         
CSingleton1::CGarbo CSingleton1::m_garbo;//            

CSingleton1::CSingleton1()
{

}

3.1.3.メモリリーク検出
vldでメモリリークを検出し、CGarboクラスが追加されていない場合、メモリリークは1バイト、すなわち、空の単一クラスインスタンスが占める1バイトであり、以下のようにする.CGarboクラスおよび静的メンバー変数を追加すると、メモリに漏れはありません.
Visual Leak Detector Version 2.3 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x003AC038: 1 bytes ----------
  Call Stack:
    d:\microsoft visual studio 9.0\projects\testcpp\testsingleton\singleton1.h (11): TestSingleton.exe!CSingleton1::getInstance + 0x7 bytes
    d:\microsoft visual studio 9.0\projects\testcpp\testsingleton\testsingleton.cpp (12): TestSingleton.exe!wmain
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (583): TestSingleton.exe!__tmainCRTStartup + 0x19 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): TestSingleton.exe!wmainCRTStartup
    0x7C81776F (File and line number not available): kernel32.dll!RegisterWaitForInputIdle + 0x49 bytes
  Data:
    CD  

3.2.静的ローカル変数の実装
3.2.1.特長
A.メモリ解放の問題を考慮する必要はありません.
B.クラスコピーとクラス付与を無効にする.
3.2.2.例
//Singleton2.h
#pragma once

class CSingleton2
{
public:

	static CSingleton2& getInstance()
	{
		static CSingleton2 instance;
		return instance;
	}

private:

	CSingleton2();
	CSingleton2(const CSingleton2 &);
	CSingleton2 & operator = (const CSingleton2 &); 

};

3.2.3.メモリ漏洩に関する問題なし