单例模式:一个类只允许存在一个对象(或多个实例共用唯一的对象),并提供他的访问方法
实现思路:
禁止在类的外部创建对象:私有化构造函数即可
类的内部维护唯一的对象:静态成员变量
提供单例对象的访问方法:静态成员函数
具体创建方式:
饿汉式:单例对象无论用或不用,程序启动即创建
#include <iostream> using namespace std; class Singleton { //单例模式--饿汉式 public: //3.通过静态成员函数获取单例对象 static Singleton& getS(void) { return S; } private: //1.私有化构造函数(包括拷贝构造) Singleton(int data=0):m_data(data){ cout << "单例对象被创建了" << endl; } Singleton(const Singleton& ); //拷贝构造可以只写声明不写定义,用编译器默认的定义 private: int m_data; //2.使用静态成员变量表示唯一的对象 static Singleton S; //声明单例对象 }; Singleton Singleton::S(123); //初始化,此时创建了对象 int main() { cout << "main函数执行了" << endl; //通过这个提示可以发现,在主函数执行前单例对象已经创建了 //Singleton a(10); 报错,因为构造函数私有化,不能创建对象,实现单例模式 Singleton& s1 = Singleton::getS(); //通过静态成员函数获取单例对象 //这种方式再获取 对象地址相同 属于同一个对象 //Singleton aa = s1;报错,因为拷贝构造函数私有化,不能创建对象,实现单例模式 return 0; }
懒汉式:单例对象用时再创建,不用即销毁
#include <iostream> using namespace std; class Singleton { //单例模式--懒汉式 public: //3.通过静态成员函数获取单例对象 static Singleton& getS(void) { if (S == NULL) { //如果是空指针说明没有创建对象 S = new Singleton(123); //创建对象 //用时再创建,所以放到这个函数中 } S_count++; return *S; } //销毁对象函数--不用即可销毁 void release(void) { S_count--; if (S_count==0) { //保存最后一个使用者再销毁 delete S; S = NULL; cout << "对象销毁了" << endl; } } private: //1.私有化构造函数(包括拷贝构造) Singleton(int data=0):m_data(data){ cout << "单例对象被创建了" << endl; } Singleton(const Singleton& ); //拷贝构造可以只写声明不写定义,用编译器默认的定义 private: int m_data; //2.使用静态成员变量指针表示唯一的对象 static Singleton* S; //声明单例对象指针 static int S_count; //记录使用者个数 }; Singleton* Singleton::S=NULL; //初始化成空指针 int Singleton::S_count = 0; int main() { cout << "main函数执行了" << endl; Singleton& s1 = Singleton::getS(); //通过静态成员函数获取单例对象 //这种方式再获取 对象地址相同 属于同一个对象 //Singleton aa = s1;报错,因为拷贝构造函数私有化,不能创建对象,实现单例模式 Singleton& s2 = Singleton::getS(); Singleton& s3 = Singleton::getS(); //s1、s2、s3指向同一个对象 //理解成三位使用者共享同一个对象 s1.release(); //销毁对象 s2.release(); s3.release(); return 0; }
#include <iostream> #include <mutex> using namespace std; class Singleton { public: static Singleton& getS(void) { static mutex mu; lock_guard<std::mutex> guard(mu); //上锁,防止别的线程进入 if (S == NULL) { S = new Singleton(123); /* 现在这个单例模式在多线程中还是有出错的机会的:两个线程几乎同时执行getS函数,此时有可能创建两个对象 解决办法:加上互斥锁 */ } S_count++; return *S; } void release(void) { S_count--; if (S_count == 0) { delete S; S = NULL; cout << "对象销毁了" << endl; } } private: Singleton(int data = 0) :m_data(data) { cout << "单例对象被创建了" << endl; } Singleton(const Singleton&); private: int m_data; static Singleton* S; static int S_count; }; Singleton* Singleton::S = NULL; int Singleton::S_count = 0; int main() { cout << "main函数执行了" << endl; Singleton& s1 = Singleton::getS(); Singleton& s2 = Singleton::getS(); Singleton& s3 = Singleton::getS(); s1.release(); s2.release(); s3.release(); return 0; }