单例模式也称为单件模式、单子模式,其应用场景是程序中需要写个类,而这个类只能产生一个实例。这个实例在全局被所有类都能够调用到,这个时候我们所使用的就是单例模式。该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出等。
而一个实例的实现方式有很多种,可以通过全局变量来实现,但这样的代码显得很不雅观。
下面举个C/S架构中客户端中用到的单例模式,这个客户端与服务器之间网络通信采用windows socket实现。而客户端程序中之需要一个socket就可以实现与服务器端通信,故一个客户端只需要开启一个socket,写一个类封装封装这个socket,封装socket的这个类就可以采用单例模式。下面说说单例模式的特点。
单例模式的要点有三个;一是某各类只能有一个实例;二是它必须自行创建这个事例;三是它必须自行向整个系统提供这个实例即以下特征:
u 它有一个指唯一实例的静态指针m_pInstance,并且是私有的。
u 它有一个公有的函数,可以获取这个唯一的实例,并在需要的时候创建该实例。
u 它的构造函数是私有的,这样就不能从别处创建该类的实例
以客户端封装socket的TKCommunication类为例,如下:
class TKCommunication
{
public:
virtual ~TKCommunication();
int Initialize(DWORD dwAddr, int iPort, HWND hWnd);
void Finalize();
int RecvData(char *strRecv, int &iNumRecv);
int SendData(const char *send);
static TKCommunication* GetInstance();
private:
TKCommunication();
static TKCommunication* m_TKComm;
SOCKET m_Socket;
HWND m_hMainWnd;
};
TKCommunication类中的TKComm成员变量就满足唯一指向实例的静态指针。
构造函数TKCommunication();为私有函数,这样保证了实例不能在别处被创建。公有函数GetInstance()用以获取这个唯一实例,并在需要的时候创建,并且保证只有一个实例。
部分实现代码如下:
//用以初始化私有静态成员变量
TKCommunication* TKCommunication::m_TKComm = NULL;
//为程序调用提供实例入口,并在需要的时候创建实例。
TKCommunication* TKCommunication::GetInstance()
{
if(NULL == m_TKComm)
{
m_TKComm = new TKCommunication();
}
return m_TKComm;
}
当程序中调用这个实例用以接收发送数据时,只需执行
iRet = TKCommunication::GetInstance()->RecvData ((char *)m_Msg);
iRet = TKCommunication::GetInstance()->SendData((char *)m_Msg);
最后,感谢高成eason提供例子。