单例设计模式:确保类的唯一实例
在软件工程中,设计模式是一组常见问题的解决方案,是解决特定问题的模板。单例(Singleton)设计模式是创建型模式的一种,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。
什么是单例模式?
单例模式的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这样做的好处是控制了实例的数量,并且可以节省系统资源。在实际应用中,比如配置管理器、线程池、缓存等场景,单例模式都非常有用。
如何实现单例模式?
在C++中,实现单例模式通常涉及以下几个步骤:
- 私有化构造函数和复制构造函数
- 提供一个私有的静态实例变量
- 提供一个公有的静态获取实例的方法
饿汉式
#includes<iostream> using namespace std; /* 单例模式:一个类不管创建多少次对象,永远只能得到该类型的一个对象实例 比如日志模块,数据库模块, 饿汉式单例模式:还没有获取实例对象,实例对象就已经产生 懒汉式单例模式:唯一的实例对象,知道第一次获取它的时候,才产生 */ //首先要先限制构造函数的访问方式 //这是饿汉式单例模式 是线程安全的 class Singlento { public: //定义一个接口 用户可以调用这个类的实例对象 static Singlento* getInstance(){// #3获取类的唯一实例对象的接口方法 return &instance; } private: static Singlento instance;//# 2 给一个实例 Singlento()//#1 构造函数私有化 { } Singlento(const Singlento&) = delete; Singlento& operator = (const Singlento&) = delete; }; Singlento Singlento::instance; int main() { Singlento *p1 = Singlento::getInstance(); Singlento *p2 = Singlento::getInstance(); Singlento *p3 = Singlento::getInstance(); //打印的结果都是一样的 return 0; }
/静态成员变量为啥在类外实现 //在C++中,静态成员变量是属于类的所有实例共享的变量。不同于非静态成员变量,静态成员变量并不属于类的任何单个实例,而是存在于所有实例之间的共享空间中。 //为了使用静态成员变量,必须在类的外部对其进行定义和初始化。这一步骤是必须的,因为它为该静态成员分配存储空间。如果在类内部声明了一个静态成员变量,那只是对其进行了声明而已,并没有定义它
懒汉式
//懒汉式 class Singlento { public: //定义一个接口 用户可以调用这个类的实例对象 static Singlento* getInstance(){// #3获取类的唯一实例对象的接口方法 if(instance == nullptr){ instance = new Singlento(); } return instance; } private: static Singlento *instance;//# 2 给一个实例 Singlento()//#1 构造函数私有化 { } Singlento(const Singlento&) = delete; Singlento& operator = (const Singlento&) = delete; }; Singlento* Singlento::instance == nullptr; int main() { Singlento *p1 = Singlento::getInstance(); Singlento *p2 = Singlento::getInstance(); Singlento *p3 = Singlento::getInstance(); //打印的结果都是一样的 return 0; }
多线程
//多线程 std::mutex mtx; class Singlento { public: //定义一个接口 用户可以调用这个类的实例对象 static Singlento* getInstance(){// #3获取类的唯一实例对象的接口方法 if(instance == nullptr){ lock_guard<mutex> guard(mtx); if(instance == nullptr){//锁+双重判断 因为要是多线程 线程二进来以后阻塞了 县城一赋值之后出去就释放锁 //线程二进来之后又要new一个这是不行的 instance = new Singlento(); } } return instance; } private: static Singlento *instance;//# 2 给一个实例 Singlento()//#1 构造函数私有化 { } Singlento(const Singlento&) = delete; Singlento& operator = (const Singlento&) = delete; }; Singlento* Singlento::instance == nullptr; int main() { Singlento *p1 = Singlento::getInstance(); Singlento *p2 = Singlento::getInstance(); Singlento *p3 = Singlento::getInstance(); //打印的结果都是一样的 return 0; }
结语
单例模式是一种强大而简单的设计模式,它通过确保只有一个实例存在,来减少资源使用并保护数据的完整性。然而,它也有缺点,比如在多线程环境中可能会变得复杂,并且可能导致代码的紧密耦合,这可能会影响到代码的可测试性