概述
-
单例模式确保一个类在整个系统生命周期中只有一个实例存在,保证其唯一性和全局访问性。
-
单例类特点:
- 构造函数和析构函数为私有,防止外部构造和析构。
- 禁用拷贝构造和赋值操作符,确保实例的唯一性。
- 提供静态函数获取实例,保证全局访问。
-
单例模式分类:
- 懒汉式:在需要时才创建实例,需要考虑线程安全。
- 饿汉式:系统启动时即创建实例,天然线程安全。
饿汉式和懒汉式简单解析
-
饿汉式实现:利用静态局部变量的特性,在程序运行时自动创建实例,线程安全,但可能提前占用内存。
-
懒汉式实现:在需要时才创建实例,通过双重检查锁定(double-checked locking)保证线程安全,避免了每次调用时都加锁的开销。
C++11 饿汉式实现
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() {} // Private constructor
};
这种方式简单且安全,确保了实例的唯一性和线程安全性。
C++11 懒汉式实现
#include <atomic>
#include <mutex>
class Singleton {
public:
static Singleton* getInstance() {
Singleton* tmp = m_instance.load(std::memory_order_acquire);
if (!tmp) {
std::lock_guard<std::mutex> lock(m_mutex);
tmp = m_instance.load(std::memory_order_relaxed);
if (!tmp) {
tmp = new Singleton;
m_instance.store(tmp, std::memory_order_release);
}
}
return tmp;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() {} // Private constructor
static std::atomic<Singleton*> m_instance;
static std::mutex m_mutex;
};
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
这段代码利用了std::atomic
和std::mutex
来实现线程安全的延迟初始化。getInstance
函数中使用双重检查锁定(double-checked locking)来避免多次初始化实例的开销,并保证线程安全。
完整测试代码
#include <iostream>
#include <thread>
void thread_func() {
Singleton::getInstance();
}
int main() {
Singleton::getInstance(); // Ensure instance creation
std::thread t(thread_func);
t.join();
return 0;
}
这段完整测试代码确保了单例模式在多线程环境下的正常运行。