单例模式:从基础实现到高级应用
- 单例模式的核心思想
- 2种经典实现方式及对比
- 单例模式的潜在问题与解决方案
-
- [1. 防止反射/克隆破化单例](#1. 防止反射/克隆破化单例)
- 2.处理析构问题
- [3. 继承单例基类](#3. 继承单例基类)
- 单例模式在工程中的实际应用
-
- [1. 日志系统](#1. 日志系统)
- [2. 数据库连接池](#2. 数据库连接池)
- 最终实现推荐
单例模式的核心思想
目的:去报一个类仅有一个实例,并提供全局访问点。
适用场景:
- 需要严格控制资源访问(如数据库连接池);
- 频繁的创建销毁对象成本高(如配置管理器);
- 共享状态管理(如全局计数器);
2种经典实现方式及对比
- 饿汉式(线程安全)
c++
class Singleton
{
priveate:
static Singleton instance; //类加载时初始化
Singleton() = default; //私有构造函数
~Singleton() = default;
public:
static Singleton* getSingleton()
{
return &instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
}
//初始化静态成员
Singleton Singleton::instance;
特点:
- 线程安全
- 可能造成资源浪费(即使不用也会初始化)
- 懒汉式(非线程安全)
c++
class Singleton
{
private:
static Singleton* instance; //静态实例指针
Singleton() = default; //私有构造函数
~Singleton() = default;
public:
static Singleton* getInstance()
{
if (instance == NULL) //线程不安全点
{
instance = new Singleton();
}
return instance;
}
//删除拷贝构造和复制构造操作
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
问题:多线程下可能创建多个实例
- meyer's singleton(C++最佳实践)
c++
class Singleton
{
public:
static Singleton& getIntance()
{
static Singleton instance; //C++11保证线程安全
return instance;
}
private:
Singleton() = default;
~Singleton() = default;
};
单例模式的潜在问题与解决方案
1. 防止反射/克隆破化单例
c++
clasee Singleton
{
//...其他代码...
private:
//防止通过反射构造
Singleton()
{
if (instance != NULL)
{
throw std::runtime_error("Singleton already exists!");
}
}
};
2.处理析构问题
c++
//方案1:智能指针自动管理
static std::shared_ptr<Singleton> getInstance() {
static std::shared_ptr<Singleton> instance(new Singleton());
return instance;
}
//方案2:显示释放接口
static void destoryInstance() {
delete instance; //需要配合线程安全处理
}
3. 继承单例基类
c++
template<typedef T>
class Singleton {
projected:
Singleton() = default;
~Singleton() = default;
public:
static T& getSingleton() {
static T instance;
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
//使用示例
class MyClass : public Singletong<MyClass> {
friend class Singleton<MyClass>;
private:
MyClass() = default;
}
单例模式在工程中的实际应用
1. 日志系统
c++
class Logger : public Singleton<Logger> {
public:
void log(const std::string& message) {
std::lock_guard<std::mutex> lock(mutex);
std::cout << "[LOG] " << message << std::endl;
}
private:
std::mutex mutex;
friend class Singleton<Logger>;
Logger() = default;
};
// 使用
Logger::getInstance().log("System started");
2. 数据库连接池
c++
class ConnectionPool : public Singleton<ConnectionPool> {
public:
Connection* getConnection() { /*...*/ }
void releaseConnection(Connection* conn) { /*...*/ }
private:
std::vector<Connection*> pool;
friend class Singleton<ConnectionPool>;
ConnectionPool() { /* 初始化连接池 */ }
};
最终实现推荐
c++
class MySingleton {
public:
static MySingleton& getInstance() {
static MySingleton instance;
return instance;
}
// 禁用拷贝和移动
MySingleton(const MySingleton&) = delete;
MySingleton& operator=(const MySingleton&) = delete;
MySingleton(MySingleton&&) = delete;
MySingleton& operator=(MySingleton&&) = delete;
private:
MySingleton() = default; // 私有构造
~MySingleton() = default;
};