基本的单例模式(饿汉式、懒汉式)
懒汉模式
懒汉模式是一种单例模式的实现方式,其特点是在首次请求获取单例实例时才进行实例化,以达到延迟加载的效果。
在懒汉模式中,通常会将构造函数设置为私有,以确保只能通过类的静态方法来获取实例。同时,为了保证实例只被创建一次,可以在静态方法中使用静态局部变量来保存单例实例。当静态方法被调用时,会首先检查静态局部变量是否已经被初始化,如果没有,则进行实例化操作,然后返回实例。
懒汉模式的优点是可以实现延迟加载,避免了在程序启动时就创建实例的开销,从而提高了程序的启动速度。然而,由于懒汉模式需要在运行时进行实例化,所以可能会在多线程环境下存在线程安全问题,需要采用线程安全措施来保证单例实例的正确性。同时,由于在每次获取实例时都需要进行线程同步的操作,所以懒汉模式的效率可能会受到一定的影响。
模板…懒汉模式
class Singleton {
public:
// 获取单例实例的静态函数
static Singleton& getInstance() {
// 使用静态局部变量确保只被初始化一次
static Singleton instance;
return instance;
}
// 假设有一些其他的公共方法...
void doSomething() {
// ...
}
private:
// 将构造函数声明为私有,确保只有这个类内部可以创建实例
Singleton() {}
};
// 使用单例模式获取实例
Singleton& s = Singleton::getInstance();
s.doSomething();
例子
#include <iostream>
using namespace std;
// 定义 SumCalculator 类
class SumCalculator {
public:
// 获取 SumCalculator 的单例实例
static SumCalculator& Get()
{
// 定义静态局部变量,确保只初始化一次
static SumCalculator instance;
return instance;
}
// 计算从 start 到 end 的整数和
int Calculate(int start, int end) {
int sum = 0;
for (int i = start; i <= end; i++) {
sum += i;
}
return sum;
}
private:
// 私有化构造函数,确保只能通过 Get 函数获取实例
SumCalculator() {}
};
// 主函数
int main() {
// 获取 SumCalculator 的单例实例模式
SumCalculator& calculator = SumCalculator::Get();
// 计算从1到100的和
int sum = calculator.Calculate(1, 100);
// 输出结果
cout << "The sum from 1 to 100 is: " << sum << endl;
return 0;
}
饿汉式
这是饿汉式单例模式的一种实现方式,它在类定义中直接定义了一个静态 Singleton 对象 instance,并在类外部进行了初始化。因此,在程序启动时就会创建该对象,因此被称为“饿汉式”,因为对象实例在使用之前就已经“饿了”。
注意,这种实现方式也是线程安全的,因为静态变量的初始化是线程安全的。然而,在某些情况下,这种实现方式可能会浪费一些资源,因为对象实例在程序启动时就已经创建了,即使在程序运行的早期阶段可能并没有用到它。
class Singleton {
public:
// 获取单例实例的静态函数
static Singleton& getInstance() {
// 定义一个静态成员变量作为实例,并在第一次调用时初始化
static Singleton instance;
return instance;
}
// 假设有一些其他的公共方法...
void doSomething() {
// ...
}
private:
// 将构造函数声明为私有,确保只有这个类内部可以创建实例
Singleton() {}
};
Singleton Singleton::instance;
#include <iostream>
using namespace std;
class Random {
public:
Random(const Random &) = delete;
static Random &Get() {
return s_Instance;
}
static float Float(){ return Get().IFloat();}
private:
float IFloat() { return m_RandomGenerator; }
Random() {}
float m_RandomGenerator = 0.5f;
static Random s_Instance;
};
Random Random::s_Instance;
int main() {
float num = Random::Float();
cout << num << endl;
}
总结
懒汉模式和饿汉式模式都是单例模式的实现方式。
懒汉模式是在第一次获取实例时才会创建实例,所以也被称为延迟加载模式。优点是节省了内存空间,缺点是在多线程环境下需要考虑线程安全问题,需要加锁来保证只有一个线程创建实例。另外,由于在第一次使用时才创建实例,所以在多次使用前都需要判断实例是否已经存在,可能会影响程序性能。
饿汉式模式是在程序启动时就会创建实例,所以也被称为预先加载模式。优点是实现简单,线程安全,可以避免多线程环境下的竞争和加锁等问题,缺点是可能会浪费一些内存空间,因为实例在程序启动时就已经创建好了,但是可能在程序执行过程中一直没有被使用。
因此,在选择懒汉模式和饿汉式模式时需要根据具体的场景需求和性能要求来进行选择。