参考
C++ 单例模式总结与剖析
什么是单例
目的:创建类中的对象,并且保证只有一个对象实例。
单例类内部实现只生成一个唯一实例,同时他提供一个静态的getInstance()
工厂方法让外部可以访问他的唯一实例。
外部不能直接创建该类的对象,因为默认构造和拷贝函数设计为私有,只能通过getInstance方法来得到这个对象。
特点:单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例;
具体使用场景
- 设备管理器,系统中可能有多个设备,但是只有一个设备管理器,用于管理设备驱动;
- 数据池,用来缓存数据的数据结构,需要在一处写,多处读取或者多处写,多处读取;
单例模式案例
主席模式
目的:为了让类中只有一个实例,实例不需要自己释放
步骤:
- 默认构造和拷贝构造私有化
- 内部维护一个私有唯一对象指针
- 对外提供getInstance方法来访问这个指针
#include <iostream>
using namespace std;
class ChairMan
{
private:
//构造函数私有化
ChairMan()
{
cout << "构造函数" << endl;
}
//拷贝构造私有化
ChairMan(const ChairMan &c)
{
cout << "拷贝构造" << endl;
}
// 创建一个静态的*singleMan对象
static ChairMan *singleMan; //内部维护一个指针
public:
//对外暴露借口,提供方法返回实例对象
static ChairMan* getInstance()
{
return singleMan; //私有的对象指针返回
}
};
//static 成员变量,内部定义外部实现
ChairMan* ChairMan::singleMan = new ChairMan;
int main()
{
ChairMan *cm1 = ChairMan::getInstance(); //不能有其他方式创建该类的实例。
}
打印机模式
#include <iostream>
using namespace std;
class Printer
{
private:
Printer() { m_Count = 0; };
Printer(const Printer &p){};
static Printer *singlePrinter;
int m_Count;
public:
static Printer *getInstance()
{
return singlePrinter;
}
void printText(string text)
{
cout << text << endl;
m_Count++;
cout << "打印机使用次数为: " << m_Count << endl;
}
};
Printer *Printer::singlePrinter = new Printer;
void test1()
{
Printer *printer = Printer::getInstance();
printer->printText(" 报告1");
printer->printText(" 报告2");
printer->printText(" 报告3");
Printer *printer2 = Printer::getInstance();
printer->printText(" 报告1");
printer->printText(" 报告2");
if (printer == printer2)
{
cout << "printer 等于 printer2 " << endl;
}
}
int main()
{
test1();
Printer *printer = Printer::getInstance();
printer->printText(" 报告1");
}
/*
报告1
打印机使用次数为: 1
报告2
打印机使用次数为: 2
报告3
打印机使用次数为: 3
报告1
打印机使用次数为: 4
报告2
打印机使用次数为: 5
printer 等于 printer2
报告1
打印机使用次数为: 6
*/
通过该代码我们发现, 使用单例模式,我们创建的是一个全局实例,全局仅有唯一实例,即使我们再getInstance, 他拿到的还是全局唯一那个实例。
这也就达到了我们的需求:有些对象我们只需要一个,比如:线程池、缓存、对话框、处理偏好设置、注册表等对象,这些对象只能有一个实例,如果制造出多个实例,就会导致很多问题产生
最推荐的懒汉式单例代码
#include <iostream>
class Singleton
{
public:
~Singleton(){
std::cout<<"destructor called!"<<std::endl;
}
Singleton(const Singleton&)=delete;
Singleton& operator=(const Singleton&)=delete;
static Singleton& get_instance(){
static Singleton instance;
return instance;
}
private:
Singleton(){
std::cout<<"constructor called!"<<std::endl;
}
};
int main(int argc, char *argv[])
{
Singleton& instance_1 = Singleton::get_instance();
Singleton& instance_2 = Singleton::get_instance();
return 0;
}
/*
constructor called!
destructor called!
*/