全球云邮登陆网站,wordpress自定义文章类型模板,网站建设服务方案,网站免费进入窗口软件2023一、单例模式简介 单例模式#xff08;Singleton Pattern#xff09;是一种创建型设计模式#xff08;GoF书中解释创建型设计模式#xff1a;一种用来处理对象的创建过程的模式#xff09;#xff0c;单例模式是其中的一种#xff0c;它确保一个类只有一个实例#xff…一、单例模式简介 单例模式Singleton Pattern是一种创建型设计模式GoF书中解释创建型设计模式一种用来处理对象的创建过程的模式单例模式是其中的一种它确保一个类只有一个实例并提供一个全局访问点来获取这个实例。这个模式适用于那些需要一个全局唯一的对象来协调系统中的行为的情况。即在整个程序运行过程中该类只存在一个对象实例。
GoF一书对单例模式的介绍 二、单例模式的用处
单例模式常见的使用场景
配置管理全局配置管理器确保配置只被加载一次并在全局范围内一致。日志记录全局日志记录器确保所有日志信息被记录在一个地方。线程池全局线程池管理避免多个线程池实例带来的资源浪费。数据库连接池全局数据库连接池统一管理数据库连接的创建和销毁
单例模式的优点包括 1. 确保全局唯一性 唯一性单例模式确保一个类只有一个实例。这对于那些需要全局唯一的资源或管理类非常重要例如配置管理器、日志记录器等。 全局访问单例模式提供了一个全局访问点来获取这个唯一实例使得所有代码都可以通过统一的方式来访问该实例。 2. 控制资源访问 资源管理在某些情况下某些资源如数据库连接、线程池只能由一个实例进行管理。使用单例模式可以有效地控制这些资源的创建和销毁避免资源的重复创建和管理。 性能优化通过避免创建多个实例单例模式可以减少系统开销和资源浪费。 3. 简化接口 简化使用由于只有一个实例使用单例模式的类不需要考虑实例的创建和管理使用时更简单直观。 一致性可以保证对全局状态的一致性和统一管理减少了不同实例间的状态不一致问题。 4. 延迟实例化 懒加载通过懒汉式实现单例模式可以实现延迟初始化即实例在第一次使用时创建从而提高系统启动速度并节省资源直到确实需要实例时才创建它。 5. 避免多次实例化 避免浪费有些对象的创建和初始化代价较高使用单例模式可以避免重复创建这些对象从而节省计算资源和时间。 三、单例模式的设计步骤
a私有化构造函数
b提供一个全局的静态方法全局访问点
c在类中定义一个静态指针指向该类的对象静态指针由全局访问点获取
四、单例模式的两种设计方法
1懒汉式Lazy Initialization
这种设计方式只有在第一次使用时才会创建实例这种方式的优点是延迟初始化。通常使用静态局部变量来实现线程安全的懒加载。
2饿汉式Eager Initialization
在这种实现中单例实例在程序启动时就被创建。也就是不管有没有被使用只要程序运行就会创建该对象。这个实现简单但如果单例实例的创建开销较大可能会导致程序启动变慢且可能会浪费资源。
懒汉式代码示例
lazy.cpp
#include iostream//Lazy Initialization
class Singleton {
public:// 获取单例实例的公共方法static Singleton getInstance() {static Singleton instance; // 静态局部变量线程安全return instance;}// 禁止复制构造函数和赋值操作符Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;// 其他成员变量和方法void doWorking() const {std::cout我是懒汉式创建型设计模式——单例模式! std::endl;}private:Singleton() {} // 私有构造函数};// 使用示例
int main() {Singleton singleton Singleton::getInstance();Singleton* ptr Singleton::getInstance();//判断是否调用同一个对象if ( singleton ptr){std::cout我们是同一个对象! std::endl;}else{std::cout我们是不同的对象! std::endl;}//调用对象的方法singleton.doWorking();ptr-doWorking();return 0;
}运行效果 饿汉式代码示例
eager.cpp
#include iostream//Eager Initialization
class Singleton {
public:// 获取单例实例的公共方法static Singleton getInstance() {return instance;}// 禁止复制构造函数和赋值操作符Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;// 其他成员变量和方法void doWorking() const {std::cout我是饿汉式创建型设计模式——单例模式! std::endl;}private:Singleton() {} // 私有构造函数static Singleton instance; // 声明静态成员};Singleton Singleton::instance; // 定义并初始化静态成员(只要程序运行就创建该实例)// 使用示例
int main() {Singleton singleton Singleton::getInstance();Singleton* ptr Singleton::getInstance();//判断是否调用同一个对象if ( singleton ptr){std::cout我们是同一个对象! std::endl;}else{std::cout我们是不同的对象! std::endl;}//调用对象的方法singleton.doWorking();ptr-doWorking();return 0;
}
运行效果 3单例模式的线程安全问题
使用饿汉式方法创建单例模式如果不使用静态局部变量而是使用裸指针判断的方式创建单例很容易引发多线程的资源竞争问题。线程在空闲状态下可以挂起
使用双重检查锁定Double-Checked Locking来确保多线程环境下的单例创建的安全性。
示例代码
doubleLock.cpp
#include iostream
#include mutex//线程安全的双重检查锁定
class Singleton {
public:static Singleton* getInstance() {if (!instance) {std::lock_guardstd::mutex lock(mutex);if (!instance) {instance new Singleton();}}return instance;}// 禁止复制构造函数和赋值操作符Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;// 其他成员变量和方法void doWorking() const {std::cout我是懒汉式单例模式——我使用了双重检查锁定保证我的创建安全! std::endl;}private:Singleton() {} // 私有构造函数//类中声明静态变量static Singleton* instance;static std::mutex mutex;};Singleton* Singleton::instance nullptr; //定义并初始化指针为空
std::mutex Singleton::mutex; //定义并初始化互斥锁// 使用示例
int main() {Singleton* singleton Singleton::getInstance();Singleton* ptr Singleton::getInstance();//判断是否调用同一个对象if (singleton ptr){std::cout我们是同一个对象! std::endl;}else{std::cout我们是不同的对象! std::endl;}//调用对象的方法singleton-doWorking();ptr-doWorking();return 0;
}
运行效果 23种设计模式中单例模式是比较简单的一种但是涉及到的知识面也是很多的比如线程、互斥、同步等。 后面我还会继续讲解其他设计模式敬请期待啦(¬‿¬)