1、定义
单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
2、介绍
优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景: 1、要求生产唯一序列号。 2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。 3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
3、源码
思路:1、在类中,定义静态成员变量和静态成员函数,通过静态成员函数对静态成员进行复制,定义新对象时可以保证类的构造函数只会被调用一次。2、将构造函数私有化,防止创建新的实例。
3.1、头文件
Emperor.h
#pragma once
#include <Windows.h>
#include <winnt.h>
#include <iostream>
using namespace std;
class Emperor
{
public:
static Emperor* getInstance();
static void releaseInstance();
void emperorInfo(void);
void setEmperorTag(string tag);
private:
Emperor(void);
virtual ~Emperor(void);
Emperor(const Emperor&);
Emperor& operator=(const Emperor&);
static Emperor *m_emperor;
static HANDLE m_mutex;
string m_emperor_tag;
class Garbo
{
public:
Garbo()
{
cout << "create garbo" << endl;
}
~Garbo()
{
cout << "destrory garbo" << endl;
getchar();
if (NULL != m_emperor)
{
WaitForSingleObject(m_mutex, INFINITE);
if (NULL != m_emperor)
{
cout << "remove instance" << endl;
delete m_emperor;
m_emperor = NULL;
}
ReleaseMutex(m_mutex);
}
if (NULL != m_mutex)
{
cout << "delete mutex" << endl;
CloseHandle(m_mutex);
m_mutex = NULL;
}
}
};
static Garbo m_garbo;
};
3.2、实现文件
Empeor.h
#include "Emperor.h"
#include <iostream>
Emperor *Emperor::m_emperor = NULL;
HANDLE Emperor::m_mutex = CreateMutex(NULL, FALSE, NULL);
Emperor::Garbo Emperor::m_garbo;
Emperor::Emperor(void)
{
cout << "create emperor instance" << endl;
}
Emperor::~Emperor(void)
{
cout << "destroy emperor instance and release its resources" << endl;
}
void Emperor::emperorInfo(void)
{
char msg_buf[50] = { 0 };
sprintf_s(msg_buf, 50, "the emperor's name is (%s)", m_emperor_tag.c_str());
string msg(msg_buf);
cout << msg.c_str() << endl;
}
Emperor *Emperor::getInstance()
{
if (NULL == m_emperor)
{
WaitForSingleObject(m_mutex, INFINITE);
if (NULL == m_emperor)
m_emperor = new Emperor();
ReleaseMutex(m_mutex);
}
return m_emperor;
}
void Emperor::releaseInstance()
{
if (NULL != m_emperor)
{
WaitForSingleObject(m_mutex, INFINITE);//定义锁,防止多线程同时访问
if (NULL != m_emperor)
{
delete m_emperor;
m_emperor = NULL;
}
ReleaseMutex(m_mutex);
}
}
void Emperor::setEmperorTag(string tag)
{
m_emperor_tag = tag;
}
main.cpp
#include "Emperor.h"
int main()
{
Emperor *pEmperor1 = Emperor::getInstance();
pEmperor1->setEmperorTag("QL");
pEmperor1->emperorInfo();
Emperor *pEmperor2 = Emperor::getInstance();
pEmperor2->emperorInfo();
Emperor *pEmperor3 = Emperor::getInstance();
pEmperor3->emperorInfo();
Emperor::releaseInstance();
system("pause");
return 0;
}
4、结果显示
参考文献:《菜鸟教程》 https://blog.csdn.net/phiall/article/details/52199659博客