单例模式的概念
单例模式是一种设计模式,限制了特定类只有一个对象,并且该对象有一个公共接口使得其在全局区域都可以被访问。
单例模式的实现思路
1.只有一个实例对象,因此程序员就不能在程序中多次创建对象,可以将构造函数放在的private访问权限中,使其私有化,不被外部调用。同时将拷贝构造函数删除,因为拷贝构造函数的实质是另外创建一个对象,不符合单例模式只有一个对象的特点。
2.不在构造函数中定义和初始化,则在类外定义和初始化,可以使用static修饰声明,使其作用域为整个程序。
3.公共接口只与类有关,可以使用静态成员函数。
单例模式的分类
在不同的语言中,单例模式的形式可能有所不同,但是单例模式大体可以分为两类,懒汉式和饿汉式,两者的主要差别是否提前创建变量。
1.饿汉式
饿汉式是提前创建一个对象,不管用不用得到,都要占用空间
#include<iostream>
using namespace std;
class singleton
{
public:
static singleton& getinstance() 公共接口
{
return instance;
}
void print()
{
cout << m_data << endl;
}
private:
static singleton instance; 声明一个静态成员变量,没有初始化
singleton(int data):m_data(data){}; 构造函数私有化
int m_data;
singleton(const singleton&) = delete; 删除拷贝构造函数
};
singleton singleton::instance(10); 在类外初始化
int main()
{
singleton& a1 = singleton::getinstance();在这一行调用公共接口,在这一行是使用引用,没有另外创建对象
a1.print(); //10
return 0;
} 饿汉式
在链接阶段,编译器和链接器会合作确定所有全局和静态变量的初始化顺序。对于静态成员变量,它们 通常按照它们在代码中的声明顺序进行初始化。 当程序开始执行时,在 main 函数之前,全局对象和静态对象(包括静态成员变量)的构造函数会被调 用,进行初始化。
2.懒汉式
懒汉式是提前声明一个静态指针,等到要用的时候在申请空间。(不使用静态对象是因为其在程序启动的时候就会初始化,不符合懒汉式的初衷)同时需要使用一个公共接口来释放空间,并且其空间本质上只有一个,所以当有多个副本时,需要记录副本数,在使用释放接口的时候,判断是否释放空间。
注释:在类中不能定义一个对象,应为其大小不确定,但是可以定义类类型的指针,因为指针的空间大小是确定的。一般是四个字节,不同的系统可能不一样。
#include<iostream>
using namespace std;
class singleton
{
public:
static singleton& getinstance() 公共接口
{
if (!instance)
{
instance = new singleton(123); 申请空间
}
count++; 将副本数更新
return *instance; instance是指针,所以使用解引用符,
}
static void relese() 检测副本数是否为零,如果为零,就释放空间,并打印“鸡你太美”
{
--count;
if (!count)
{
delete instance;
instance = NULL;
cout << "鸡你太美" << endl;
}
}
void print()
{
cout << m_data << endl;
}
private:
singleton(int data):m_data(data){} 构造函数私有化
singleton(singleton&) = delete; 拷贝构造函数删除
static singleton*instance; 静态对象指针
static int count; 记录已经有的对象副本
int m_data;
};
int singleton::count = 0; 静态成员变量初始化
singleton* singleton::instance(NULL); 静态指针初始化为空指针
int main()
{
singleton& s1 = singleton::getinstance();
singleton& s2 = singleton::getinstance();
s2.print(); 123
s1.print(); 123
s2.relese(); 不会打印“鸡你太美”
s1.relese(); 检测到副本数为零,打印“鸡你太美”; 这句话只会打印一遍
return 0;
}//懒汉式
单例的特点和用途
1. 全局唯一实例:无论尝试多少次实例化这个类,它都只会返回一个对象实例。
2. 减少资源消耗:当一个类只需要一个对象实例时,使用单例模式可以避免创建多个对象,从而减少 资源消耗。
3. 提供访问控制:单例模式可以确保对资源的访问是同步的,从而避免多线程环境下的并发问题