C++设计模式——单例模式

单例设计模式

应用场景

当多个类都需要调用某一个类的一些公共接口,同时不想创建多个该类的对象,可以考虑将该类封装为一个单例模式。

特点

单例模式的特点:
1.只有一个单例对象。因而构造函数需要私有化,不能被外界访问。同时也不能进行对象的拷贝和赋值操作,故而也需要将拷贝构造函数和赋值运算符重载函数删除或者私有。
2.提供对外获取实例对象的公共访问接口。其它类可以通过这个接口获取单例对象。

设计模式分类

单例模式可以分为懒汉模式和饿汉模式。

所谓懒汉模式,就是当程序运行过程中需要单例对象的时候再创建。

所谓饿汉模式,就是定义类的时候就创建单例对象。

懒汉设计模式

1.懒汉设计模式下的单例模式,如果项目很简单,不需要考虑多线程的问题,可以这样编写懒汉模式下的单例模式。

cpp 复制代码
class Singleton
{
private:
	Singleton()=default;
	Singleton(const Singleton&)=delete;
	Singleton& operator=(const Singleton&) = delete;
public:
	static Singleton* getInstance() 
	{
		if (m_pInstance == nullptr)
		{
			m_pInstance = new Singleton;
		}
		return m_pInstance;
	}
private:
	static Singleton *m_pInstance;
	static mutex m_mutex;
};
Singleton *Singleton::m_pInstance = nullptr;
mutex Singleton::m_mutex;

2.下面是懒汉设计模式下的单例模式示例,这里考虑多线程,故而引入双重检查锁来保护单例对象的创建,是线程安全的。

cpp 复制代码
class Singleton
{
private:
	Singleton()=default;
	Singleton(const Singleton&)=delete;
	Singleton& operator=(const Singleton&) = delete;
public:
	static Singleton* getInstance() 
	{//双重检查锁定
		if (m_pInstance == nullptr)//注意这里的判断条件
		{
			lock_guard<mutex> locker(m_mutex);//注意这里的参数
			if (m_pInstance == nullptr)
			{
				m_pInstance = new Singleton;
			}
		}
		return m_pInstance;
	}
private:
	static Singleton *m_pInstance;
	static mutex m_mutex;
};
Singleton *Singleton::m_pInstance = nullptr;
mutex Singleton::m_mutex;

3.还可以在支持C++11的编译器基础之上,使用static创建懒汉模式下的单例对象。(并发程序中会等待变量初始化完成)也是线程安全的。

cpp 复制代码
class Singleton 
{
private:
	Singleton() = default;
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton &) = delete;
public:
	static Singleton* getInstance() 
	{
		static Singleton instance;
		return &instance;//注意返回的指针,若返回变量对象,会调用拷贝构造函数出现错误
	}
};

饿汉设计模式

这里提供两种编写的方式,但无论哪种,都是先创建实例对象。

1.以指针的形式创建对象。

cpp 复制代码
class Singleton
{
private:
	Singleton() = default;
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
public:
	static Singleton* getInstance()
	{
		return m_pInstance;
	}
private:
	static Singleton *m_pInstance;
};
Singleton* Singleton::m_pInstance = new Singleton;

2.以对象的方式创建。

cpp 复制代码
class Singleton 
{
private:
	Singleton() = default;
	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;
public:
	static Singleton* getInstance() 
	{
		return &m_instance;
	}
private:
	static Singleton m_instance;
};
Singleton Singleton::m_instance;

使用

编写的测试代码

这里创建两次单例对象,输出对象的地址,看看是否是同一个实例。

cpp 复制代码
Singleton *p1 = Singleton::getInstance();
Singleton *p2 = Singleton::getInstance();
cout << "p1:" << p1 << " p2:" << p2 << endl;

运行结果

注意:本文没有给出编程过程中实际需要的头文件,测试代码也只给出用于测试的部分。

相关推荐
octopus_c19 分钟前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
青少儿编程课堂22 分钟前
2026蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:堆排序与优先队列解析
c++·python·算法·bfs·信息学竞赛
j7~28 分钟前
【C++ 面试笔记】(篇二):类与数据抽象 & STL 容器与算法
开发语言·c++·面试·stl容器和算法·类和数据抽象
Fuyo_11191 小时前
深入解析 C++ unordered_set 与 unordered_map 的核心特性与性能实战
开发语言·c++
电子科技圈1 小时前
Arm电机控制开发工具哪家强?
arm开发·单片机·嵌入式硬件·设计模式·软件构建
码匠许师傅1 小时前
【C++三方组件】FFmpeg:音视频处理的瑞士军刀
c++·ffmpeg·音视频
ShineWinsu1 小时前
对于Qt:QPushButton常见属性的解析
开发语言·c++·qt·api·gui·按钮·qpushbutton
Lhan.zzZ1 小时前
用 Qt 构建线程安全的通讯静态库:从线程亲和性到完整工程
c++·vscode·qt·tcp/ip·udp
xiaoye-duck2 小时前
《C++ 项目:手写大模型接入 SDK》DeepSeek接口设计(上):初始化和全量响应
开发语言·网络·c++·语言模型
fpcc2 小时前
跟我学c++中级篇—streambuf在glog中的应用分析
开发语言·c++