当前位置: 首页 > news >正文

C++的单例模式

忘记之前有没有写过单例模式了。
再记录一下:
我使用的代码:

#ifndef SINGLETON_MACRO_HPP
#define SINGLETON_MACRO_HPP#define SINGLETON_DECL(class_name) \
public: \static class_name& instance() { \static class_name s_instance; \return s_instance; \} \
private: \class_name();\class_name(const class_name&) = delete; \class_name& operator=(const class_name&) = delete;#endif // SINGLETON_MACRO_HPP

双锁单例:

#include <iostream>
#include <mutex>class Singleton {
private:static Singleton* instance;static std::mutex mtx;// 私有化构造函数,确保不能在类外部进行实例化Singleton() {}public:// 删除复制构造函数和复制赋值操作符Singleton(const Singleton& other) = delete;Singleton& operator=(const Singleton& other) = delete;static Singleton* getInstance() {if (instance == nullptr) { // 判断实例是否已经被创建,提高效率std::lock_guard<std::mutex> lock(mtx); // 锁定if (instance == nullptr) { // 再次检查,以确保线程安全instance = new Singleton();}}return instance;}
};// 初始化静态成员
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;int main() {Singleton* s1 = Singleton::getInstance();Singleton* s2 = Singleton::getInstance();if (s1 == s2) {std::cout << "Both instances are identical." << std::endl;} else {std::cout << "Instances are different." << std::endl;}return 0;
}

单例模式的不同实现方式各有优缺点

双检锁(Double Checked Locking):

优点:
线程安全。
在实例已经被创建之后,直接返回实例,避免了每次获取实例时都需要获取锁的开销。
缺点:
代码相对复杂。
在某些老的编译器或硬件架构上,双检锁可能无法正常工作,可能需要内存屏障或其他同步机制。

静态局部变量(Meyers’ Singleton):
class Singleton {
public:static Singleton& getInstance() {static Singleton instance;return instance;}
private:Singleton() {}
};

优点:
线程安全(在 C++11 及以后的版本中)。
代码简单、清晰。
延迟初始化:只有在首次调用 getInstance 时,实例才会被创建。
缺点:
对于老的 C++ 标准(C++11 之前),这种方法可能不是线程安全的。

饿汉式:
class Singleton {
private:static Singleton instance;Singleton() {}
public:static Singleton& getInstance() {return instance;}
};

优点:
线程安全,因为实例在程序开始时就已经被初始化。
代码简单。
缺点:
实例在程序开始时就被创建,即使它从未被使用,可能会导致不必要的资源占用或初始化开销。

懒汉式(简单):
class Singleton {
private:static Singleton* instance;Singleton() {}
public:static Singleton* getInstance() {if (!instance) {instance = new Singleton();}return instance;}
};

优点:
实现简单。
延迟初始化,只在首次获取实例时创建。
缺点:
非线程安全。如果多个线程同时尝试创建实例,可能导致多个实例被创建。

在实际的使用场景中,要根据具体的需求和上下文来选择合适的实现方法。例如,如果线程安全性很重要,那么使用双检锁或C++11及以后版本的静态局部变量方法可能更合适。

最后问题:我用的是什么模式??

http://www.lryc.cn/news/151896.html

相关文章:

  • Spring Boot 中 Nacos 配置中心使用实战
  • 学生管理系统VueAjax版本
  • 迭代器模式简介
  • 四方定理c++题解
  • ZDH-权限模块
  • 漏洞修复:在应用程序中发现不必要的 Http 响应头
  • 什么是mkp勒索病毒,中了mkp勒索病毒怎么办?勒索病毒解密数据恢复
  • db2迁移至oracle
  • webpack学习使用
  • 按钮控件之2---QComboBox 复选按钮/复选框控件
  • 【数据分享】2006-2021年我国省份级别的燃气相关指标(免费获取\20多项指标)
  • C语言深入理解指针(非常详细)(二)
  • Web3j 继承StaticStruct的类所有属性必须为Public <DynamicArray<StaticStruct>>
  • Kubernetes(k8s)上安装Prometheus和Grafana监控
  • 黑马 软件测试从0到1 常用分类 模型 流程 用例
  • 面试中的商业思维:如何展示你对业务的理解
  • Docker切换文件系统为VFS
  • Spring Security存在认证绕过漏洞 CVE-2021-22096
  • 前端list列表自定义图标并设置大小
  • Multisim14.0仿真(五)三角波发生器
  • 使用安全复制命令scp在Windows系统和Linux系统之间相互传输文件
  • SOC总线学习记录之ICB(Internal Chip Bus)
  • rabbitMQ手动应答与自动应答
  • java对象创建的过程
  • WireShark流量抓包详解
  • 【密码学代码分享】突破ECDSA算法封装--JS无三方包纯手写ECDSA
  • stable diffusion实践操作-文生图
  • Spring容器及实例化
  • # Go学习-Day9
  • chatGPT如何在Java中使用