1.作用
单例模式目的就是为了保证一个类只有一个实例。
2.原理
(1)私有静态指针变量实现:使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。
(2)静态局部变量实现:在公有静方法中定义指向该类的一个静态局部变量,并返回该静态局部变量。
3.实现
3.1.私有静态指针变量实现
3.1.1.特点
A.它有唯一一个私有的、指向类的的静态成员指针m_pInstance。
B.它有一个公有的暴露该单例的静态方法getInstance。
C.构造函数是私有的,避免从其他地方创建该类实例。
D.定义单例类中私有内嵌类CGarbo,在其析构函数中释放单例指针。
E.定义CGarbo类的一个实例作为静态成员变量,利用程序结束系统会自动析构所有全局变量的特性来自动释放单例指针。
3.1.2.示例
[cpp]
//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;//程序结束,系统会自动调用其析构函数
};
[cpp]
//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个字节,如下。添加CGarbo类及静态成员变量后,内存无泄漏。
[html] view plaincopy
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.示例
[cpp]
//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.无内存泄漏相关问题