单例模式(Singleton Pattern) 一种创建型设计模式,用于确保一个类只能创建一个实例,并提供一个全局访问该实例的方式。
定义一个单例类:
- 私有化它的构造函数,以防止外界创建单例类的对象;
- 使用类的私有静态变量指向类的唯一实例;
- 使用一个公有的静态方法获取该实例。
单例模式有两种实现方式:
- 懒汉版(Lazy Singleton)
- 饿汉版(Eager Singleton)
懒汉版
单例实例在第一次被使用时才进行初始化,这叫做延迟初始化。
class singleton {
public:
// 获取单例实例的方法
static singleton& get() {
static singleton instance; // C++11标准保证线程安全的局部静态变量初始化
return instance;
}
singleton(const singleton&) = delete; // 禁用复制构造函数
singleton& operator=(const singleton&) = delete; // 禁用赋值运算符
private:
singleton() {}
~singleton() {}
};
饿汉版
单例实例在程序运行时被立即执行初始化
#include <iostream>
using namespace std;
class singleton {
public:
static singleton& get() {
return instance;
}
void show() { cout << "I'm singleton" << endl; }
singleton(const singleton&) = delete;
singleton& operator=(const singleton&) = delete;
private:
singleton() { cout << "construct" << endl; }
~singleton() {}
static singleton instance;
};
/*********测试代码****************/
#include "test.h"
singleton singleton::instance; // 默认初始化
int main()
{
singleton::get().show();
return 0;
}
// 输出
construct
I'm singleton
总结
- 使用对象,而不是指针,可以避免内存泄漏的问题。
- 这两个版本的实现都保证了线程安全
- 饿汉版要注意 instance 的初始化一定要在调用 get() 之前,否则会返回一个空对象
单例模式使用场景
-
全局配置管理:单例模式可以用于管理全局的配置信息,确保系统中的配置信息只有一个实例,并且可以在任何地方被访问。
-
资源管理:单例模式可以用于管理共享的资源,例如数据库连接池、线程池等,确保这些资源在系统中只有一个实例,避免资源浪费和冲突。
-
日志记录:单例模式可以用于记录系统的日志信息,确保日志的记录和管理在系统中只有一个实例。
-
应用程序的控制:单例模式可以用于控制应用程序的行为和状态,例如应用程序的配置信息、用户登录状态等。
注意
单例模式并不是适用于所有情况的通用解决方案,因为它可能引入全局状态和隐藏依赖,导致系统的复杂性增加。在使用单例模式时,需要仔细考虑系统的设计和需求,并合理地选择适用场景,避免滥用。