目录
1、什么是单例模式?
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,那么这时候就可以采用单例模式。
1.1、单例模式特点
在单例类的内部实现只生成一个实例,同时它提供了一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其默认构造函数和拷贝构造函数设计为私有;在单例类内部定义一个Singleton类型的静态对象,作为外部共享的唯一实例。
1.2、单例模式优缺点
优点:
- 只有一个实例,减少内存开支。应用在一个经常被访问的对象上。
- 减少系统的性能开销,应用启动时,直接产生一单例对象,用永久驻留内存的方式。
- 避免对资源的多重占用。
- 可在系统设置全局的访问点,优化和共享资源访问。
缺点:
- 一般没有接口,扩展困难。原因:接口对单例模式没有任何意义;要求“自行实例化”,并提供单一实例,接口或抽象类不可能被实例化。(当然,单例模式可以实现接口、被继承,但需要根据系统开发环境判断)
- 单例模式对测试是不利的。如果单例模式没完成,是不能进行测试的。
- 单例模式与单一职责原则有冲突。原因:一个类应该只实现一个逻辑,而不关心它是否是单例,是不是要单例取决于环境;单例模式把“要单例”和业务逻辑融合在一个类。
2、单例模式--打印机的实现
class Printer {
//定义一个静态对象指针变量,保存唯一实例地址
private:
static Printer* SinglePrint;
private:
Printer(){}
Printer(const Printer &ob) {}
//获得单例指针
public:
int count=0;
static Printer* getSinglePrint() {
if(SinglePrint == NULL){
SinglePrint = new Printer;
static CGarhuishou c;//类中嵌套类 用来析构单例类
}
return SinglePrint;
}
class CGarhuishou
{
public:
~CGarhuishou(){
if (Printer::SinglePrint != NULL) {
delete Printer::SinglePrint;
SinglePrint = NULL;
}
}
};
void printtext(const char* str) {
cout << "打印" << str << endl;
count++;
}
};
Printer* Printer::SinglePrint = NULL;
void Init() {
//打印任务一
Printer* p1 = Printer::getSinglePrint();
p1->printtext("体检报告");
p1->printtext("离职报告");
p1->printtext("成绩单");
//打印任务二
Printer* p2 = Printer::getSinglePrint();
p2->printtext("体检报告");
p2->printtext("离职报告");
p2->printtext("成绩单");
cout << "打印任务总数:" << p2->count << endl;
}
int main() {
Init();
return 0;
}
运行结果:
3、单例模式 --多线程的使用
#include<iostream>
#include<mutex>
#include<thread>
using namespace std;
std::once_flag m_falg;
//单例模式中有且只能有一个对象
class MGS
{
mutex ms1;
static void creatInstance() {
m_instance = new MGS;
static CGarhuishou c;//类中嵌套类 用来析构单例类
}
private:
MGS() {};
private:
static MGS* m_instance;//静态成员变量 生命周期为程序运行结束
public:
static MGS* getInstance() {
//if (m_instance == NULL) {
// unique_lock<mutex> as1(ms1);
// if (m_instance == NULL) {
// m_instance = new MGS;
// static CGarhuishou c;//类中嵌套类 用来析构单例类
// }
//}
//call_once()函数的作用是使可调用对象只被执行一次
call_once(m_falg, creatInstance);//表示函数第二个参数的函数只被执行一次,相当于互斥量
//第一个参数作为标志位,标志是否访问
chrono::milliseconds dura(10000);
this_thread::sleep_for(dura);
cout << "call_once执行完毕" << endl;
return m_instance;
}
void test() {
cout << "测试" << endl;
}
class CGarhuishou
{
public:
~CGarhuishou() {
if (MGS::m_instance != NULL) {
delete MGS::m_instance;
m_instance = NULL;
}
}
};
};
//静态成员类外定义
MGS* MGS::m_instance = NULL;
void mystr() {
cout << "线程开始执行" << endl;
MGS* ob1 = MGS::getInstance();
ob1->test();
cout << "线程结束" << endl;
}
void test01() {
thread th1(mystr);
thread th2(mystr);
th1.join();
th2.join();
}
int main(void) {
test01();
return 0;
}
运行结果: