单例模式:从基础实现到高级应用

单例模式:从基础实现到高级应用

单例模式的核心思想

目的:去报一个类仅有一个实例,并提供全局访问点。

适用场景:

  1. 需要严格控制资源访问(如数据库连接池);
  2. 频繁的创建销毁对象成本高(如配置管理器);
  3. 共享状态管理(如全局计数器);

2种经典实现方式及对比

  1. 饿汉式(线程安全)
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;

特点:

  • 线程安全
  • 可能造成资源浪费(即使不用也会初始化)
  1. 懒汉式(非线程安全)
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;
};

问题:多线程下可能创建多个实例

  1. 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;
};
相关推荐
数据皮皮侠AI2 天前
顶刊同款!中国地级市风灾风险与损失数据集(2000-2022)|灾害 / 环境 / 经济研究必备
大数据·人工智能·笔记·能源·1024程序员节
Fab1an3 天前
Busqueda——Hack The Box 靶机
linux·服务器·学习·1024程序员节
技术专家4 天前
Stable Diffusion系列的详细讨论 / Detailed Discussion of the Stable Diffusion Series
人工智能·python·算法·推荐算法·1024程序员节
学传打活6 天前
古代汉语是源,现代汉语是流,源与流一脉相承。
微信公众平台·1024程序员节·汉字·中华文化
学传打活11 天前
【边打字.边学昆仑正义文化】_19_星际生命的生存状况(1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
unable code18 天前
[HNCTF 2022 WEEK2]ez_ssrf
网络安全·web·ctf·1024程序员节
unable code19 天前
[NISACTF 2022]easyssrf
网络安全·web·ctf·1024程序员节
unable code20 天前
BUUCTF-[第二章 web进阶]SSRF Training
网络安全·web·ctf·1024程序员节
开开心心就好21 天前
进程启动瞬间暂停工具,适合调试多开
linux·运维·安全·pdf·智能音箱·智能手表·1024程序员节
仰泳之鹅22 天前
【51单片机】第一课:单片机简介与软件安装
单片机·嵌入式硬件·51单片机·1024程序员节