c++设计模式:单件模式(Singleton Pattern)

C++ Singleton深度解析:保护、重用与生存期管理 Singleton(单例模式)是面向对象编程中基础而关键的创建型设计模式,其核心在于确保一个类仅有一个实例并提供全局访问点。它涉及构造控制、拷贝/移动语义约束、线程安全初始化及析构时机管理等底层原理。技术价值体现在对全局状态的可控封装、资源复用效率提升以及跨模块生命周期协同;典型应用场景包括日志管理器、配置加载器、数据库连接池等需强一致性和唯一性的系统服务。本文聚焦C++语言特性下的Singleton实现本质,深入剖析构造函数私有化、CRTP继承陷阱、std::call_once线程安全机制、atexit销 阅读详情

转自:http://www.cnblogs.com/osyun/archive/2011/12/29/2306765.html

定义:单件模式确保一个类只有一个实例,并提供一个全局访问点

[【本质是把构造函数设为私有的并想办法在内存只保存自己对象的一份实例,不仅达到只创建一份实例的目的,而且可以直接通过类名直接获取在堆中的实例对象】

实现一:

复制代码
#include <iostream>
using namespace std;

class CSingleton
{
public:
    static CSingleton* getInstance();
    static void cleanInstance();
    int getValue();
    void setValue(int iValue);
private:
    int m_iValue;
    static CSingleton* m_pSingleton;
    CSingleton();
    ~CSingleton();
};

CSingleton* CSingleton::m_pSingleton = NULL;

CSingleton::CSingleton()
{
    cout << "Constructor" << endl;
}

CSingleton::~CSingleton()
{
    cout << "Destructor" << endl;
}

CSingleton* CSingleton::getInstance()
{
    if (NULL == m_pSingleton)
    {
        m_pSingleton = new CSingleton();
    }
    return m_pSingleton;
}

void CSingleton::cleanInstance()
{
    delete m_pSingleton;
}

int CSingleton::getValue()
{
    return m_iValue;
}

void CSingleton::setValue(int iValue)
{
    m_iValue = iValue;
}

int main()
{
    CSingleton* pSingleton1 = CSingleton::getInstance();
    CSingleton* pSingleton2 = CSingleton::getInstance();
    pSingleton1->setValue(123);
    if (pSingleton1->getValue() == pSingleton2->getValue())
    {
        cout << "Two objects is the same instance" << endl;
    }
    else
    {
        cout << "Two objects isn't the same instance" << endl;
    }

    CSingleton::cleanInstance();
    return 0;
}
复制代码

相信大多数的同仁都喜欢使用上边这种单件模式的实现方法,如果在单线程的情况下,是没有问题的,但如果是多线程,那么就极有可能会返回两个不同的对象,在调用

CSingleton::getInstance的时候,两个线程如果都同时运行完if判断,而又还没有调用到构造函数的话,想象下后果吧。那该怎么办呢?看下边这个实现吧。
实现二:
复制代码
#include <iostream>
using namespace std;

class CSingleton
{
public:
    static CSingleton* getInstance();
    static void cleanInstance();
    int getValue();
    void setValue(int iValue);
private:
    int m_iValue;
    static CSingleton* m_pSingleton;
    CSingleton();
    ~CSingleton();
};

// 在进程运行开始就实例化该单件,又称“急切”创建实例
CSingleton* CSingleton::m_pSingleton = new CSingleton();

CSingleton::CSingleton()
{
    cout << "Constructor" << endl;
}

CSingleton::~CSingleton()
{
    cout << "Destructor" << endl;
}

CSingleton* CSingleton::getInstance()
{
    return m_pSingleton;
}

void CSingleton::cleanInstance()
{
    delete m_pSingleton;
}

int CSingleton::getValue()
{
    return m_iValue;
}

void CSingleton::setValue(int iValue)
{
    m_iValue = iValue;
}

int main()
{
    CSingleton* pSingleton1 = CSingleton::getInstance();
    CSingleton* pSingleton2 = CSingleton::getInstance();
    pSingleton1->setValue(123);
    if (pSingleton1->getValue() == pSingleton2->getValue())
    {
        cout << "Two objects is the same instance" << endl;
    }
    else
    {
        cout << "Two objects isn't the same instance" << endl;
    }

    CSingleton::cleanInstance();
    return 0;
}
复制代码
哈哈,看清楚了吗?就是在进程运行的时候就对这个单件进行实例化,可是这样似乎又不能达到延迟实例化的目的啦。如果我们的对象对资源占用非常大,而我们的进行在整个过程中其实并没有用到这个单件,那岂不是白白浪费资源了嘛。还有更好的办法。
实现三:【发现还可以用在把很多全局的对象包在一个静态单件中来使用】
复制代码
#include <iostream>
using namespace std;

class CSingleton
{
public:
    static CSingleton* getInstance();
    int getValue();
    void setValue(int iValue);
private:
    int m_iValue;
    CSingleton();
    ~CSingleton();
};

CSingleton::CSingleton()
{
    cout << "Constructor" << endl;
}

CSingleton::~CSingleton()
{
    cout << "Destructor" << endl;
}

CSingleton* CSingleton::getInstance()
{
    static CSingleton single;
    return &single;
}

int CSingleton::getValue()
{
    return m_iValue;
}

void CSingleton::setValue(int iValue)
{
    m_iValue = iValue;
}

int main()
{
    cout << "Process begin" << endl;
    CSingleton* pSingleton1 = CSingleton::getInstance();
    CSingleton* pSingleton2 = CSingleton::getInstance();
    pSingleton1->setValue(123);
    if (pSingleton1->getValue() == pSingleton2->getValue())
    {
        cout << "Two objects is the same instance" << endl;
    }
    else
    {
        cout << "Two objects isn't the same instance" << endl;
    }
    return 0;
}
复制代码
看下运行结果吧:

Process begin
Constructor
Two objects is the same instance
Destructor

是不是跟预想的一样呢?把单件声明为成员函数中的静态成员,这样既可以达到延迟实例化的目的,又能达到线程安全的目的,而且看结果的最后,是不是在程序退出的时候,还自动的调用了析构函数呢?这样我们就可以把资源的释放放到析构函数里边,等到程序退出的时候,进程会自动释放这些静态成员的。

 
参考图书:《Head First 设计模式》

 

RKNN 端侧部署必看:YOLOv11 Pose 姿态估计模型转换与性能优化实战 随着人工智能技术在边缘计算领域的快速发展,姿态估计作为计算机视觉的重要分支,在智能监控、人机交互、体感游戏等场景中展现出巨大的应用潜力。本文深入研究了YOLOv11 Pose模型在Rockchip RKNN平台上的部署方案,从理论基础、模型转换、平台优化到实际部署进行了全面阐述。通过详细的技术分析和实验验证,证明了RKNN平台能够有效提升YOLOv11 Pose的推理性能,在RK3588硬件平台上实现了高达100 FPS的实时姿态检测,为边缘计算场景下的姿态估计应用提供了高效的解决方案。 阅读详情

相关推荐

5G NR切换测量事件解析:从A1到B2的实战应用指南

本文深入解析5G NR切换测量事件,从A1到B2的实战应用指南。详细介绍了系统内切换事件(A1-A6)和系统间切换事件(B1-B2)的触发条件与配置建议,帮助优化网络性能。通过实际案例分享,展示如何调整参数提升切换成功率和降低乒乓切换率,适用于5G网络优化工程师。

tcp8optimizer的博客 512

C++设计模式(一)——单件模式(单例模式)

  该模式的核心思想是保证一个类仅有一个实例,并提供一个该实例的全局访问点。 class Singleton { private: Singleton(); Singleton(const Singleton& other); public: static Singleton* getInstance(); static Singleton* m_instance; }; Singleton* Singleton::m_instance=nullptr; //线程非安全版本

图像学习之旅 363

03 Aras Innovator二次开发-服务端方法(二)

Aras Innovator二次开发-服务端方法书写

企业信息化(PLM,ERP.MES) 2014

C++设计模式——单件模式(singleton pattern)

一、原理讲解 由于单件模式也称为单例模式,分为懒汉式单例模式和饿汉式单例模式,两者主要区别是类对象的返回是在编译时创建?还是调用时才创建?其中,懒汉式单例模式是在程序调用时才创建,而饿汉式单例模式是在程序编译时期创建类实例。懒汉式是非线程安全的,而饿汉式是线程安全的。因为项目中用懒汉式比较多,所以本文主要总结的是懒汉式单例模式。饿汉式单例模式可以参考博主这篇文章:单例模式(饿汉式) 1.1意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 1.2应用场景 当一个类只有一个实例,而且客户端可以从一

净无邪博客 2111

从零搭建A股量化交易系统:开源框架选型与实战部署指南

本文详细介绍了从零搭建A股量化交易系统的完整流程,重点分析了开源框架VNPY和QMT的选型与实战部署。内容涵盖系统架构设计、策略开发、性能优化及实盘过渡方案,为开发者提供了一套完整的A股实盘量化交易解决方案,助力高效构建稳定可靠的量化交易系统。

sugar的博客 1271

apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】

这个是最最简单的反编译操作了。写这个教程的目的是其中很多粉丝要求出一点入门的教程。当然演示的是使用MT来操作。还有很多类似的软件可以达到目的。例如NP apltool等等或者电脑端也有很多反编译软件修改。对于玩机用户来说。也可以在系统包里直接修改一些app。

小马哥的专栏 7261

C++设计模式单件模式(单线程)Singleton pattern

在 `main` 函数中,我们创建了两个指针变量 `singleton1` 和 `singleton2`,并分别通过 Singleton 类的静态方法 `getInstance()` 获取实例。我们通过打印指针变量地址的方式来证明这一点,并通过调用 `doSomething()` 方法来验证单例模式的正确性。在 `getInstance()` 方法中,我们使用了静态变量 `instance` 来保存唯一的类实例,并在第一次使用该方法时创建了唯一的实例。// 静态变量初始化。

guoguo0524的博客 534

图形推理2-四大类六提示

图形推理笔记2

小y的学习笔记 6739

Head First 设计模式 (五) 单件模式(Singleton pattern) C++实现

单件模式确保一个类只有一个实例,并提供一个全局访问点。 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程的问题。 代码链接:点击打开链接 单件模式类图: 源代码: #ifndef CHOCOLATEBOILER_H #define CHOCOLATEBOILER_H #include<iostream> ...

weixin_30446197的博客 68

C#与天文观测:Celestia模拟星空的奇幻之旅

Celestia就像一艘穿梭在星海中的小飞船,带领我们遨游宇宙。C#则是这艘飞船的智能导航系统,用代码指挥它飞向任何我们向往的星球或星系。首先,下载并安装Celestia,熟悉其基本操作和功能。创建一个星空目标列表,包括不同的恒星、行星和星系。// 示例:定义观察目标列表new SpaceObject("太阳"),new SpaceObject("月球"),new SpaceObject("火星")

java专栏 1456

Power Switch与Tap Cell关系

tap cell可以选用一般类型的tap cell,无须secondary pg pin,因为此时switch cell的阱电位接到输入power net上了,switch cell可以正常上电,也可以给core内正常供电,tap cell的阱电位接switch cell输出的power,需要注意的是此时switch cell与core内其他cell的阱电位是不同的,所以为了避免drc问题,需要在switch上盖hard blockage或者keepout margin。2)自带阱偏置的switch。

m0_61544122的博客 2334

C++设计模式单件模式(多线程)Singleton pattern双检查锁mutex/atomic

【代码】C++设计模式单件模式(多线程)Singleton pattern双检查锁mutex/atomic。

guoguo0524的博客 215

第4节:cesium 0基础发布离线地图(含源码+视频)

cesium发布离线地图

qq_29384639的博客 1595

招聘搜索列表一进去,发布时间就能看清:boss-show-time

求职者在搜索列表页里,每张卡片只写"本周发布""近期",岗位到底是昨天的还是两个月前的,分辨不出来。boss-show-time 把精确的发布时间写回 Boss 直聘、智联招聘、前程无忧、拉勾招聘四个平台的列表卡片,并按发布早晚着色,同时记下你第一次看到每个职位的时刻。 ## 它能替你做什么 **一眼分辨岗位新旧**。时间标签位于卡片右上方,背景色随发布天数变化:7 天内绿、8~14 天浅绿、

gitblog_00789的博客 147

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

单件模式(Singleton Pattern)之C++实现

单件模式确保一个类只有一个实例,并提供一个全局访问点。 #include #include using namespace std; class Singleton { public: static Singleton* GetInstance(); void print(); void write(string strTmp); private: Singleton(); sta

张小帅的专栏 987

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

设计模式十:单件模式 (Singleton Pattern)

特性饱汉模式饿汉模式初始化时机第一次调用getInstance()时程序启动时线程安全需要额外处理天生线程安全资源占用按需分配,节省资源始终占用资源实现复杂度较复杂(需处理线程安全)较简单适用场景初始化耗时或资源占用大的对象初始化快且一定会使用的对象。

weixin_43050542的博客 706

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C++实现单件模式Singleton Pattern

单件模式确保一个类只有一个实例,并提供一个全局访问点。

优快云er_2015的博客 433

C++设计模式之三:Singleton Pattern

        Singleton模式解决问题十分常见,我们怎样去创建一个唯一的变量(对象)?在基于对象的设计中我们可以通过创建一个全局变量(对象)来实现,在面向对象和面向过程结合的设计范式(如C++中)中,我们也还是可以通过一个全局变量实现这一点。但是当我们遇到了纯粹的面向对象范式中,这一点可能就只能是通过Singleton模式来实现了。 Singleton模式典型的结构图为 

yyyuhan的专栏 634

创建型模式之单件模式(Singleton Pattern )C++实现

单件模式(Singleton Pattern)创建型模式 定义:确保一个类只有一个实例,并提供全局访问点。 用来创建独一无二,只能有一个实例的对象的入场券。它是所有设计模式类图中最简单的。该模式在开发中非常有用。 实现单件模式需要私有的构造器、一个静态的方法和一个静态的变量。 该模式通常与抽象工厂模式或工厂模式配合使用,因为我们只需要一个工厂来创建对象。 该模式最简单,C++的实

xiaoding133的专栏【Stay hungry,Stay foolish】 1231

Head First 设计模式——单件模式(Singleton Pattern)

单件模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点 单件模式确保程序中一个类最多只有一个实例。我们在程序中会遇到这种情况如:线程池,缓存,对话框,打印机,显卡等设备驱动程序。这些类对象只能有一个实例,如果制造多个实例,就会导致许多问题产生。 经典的单件模式实现: #include using namespace std; class

ZJU_Sutton的专栏 1262

【设计模式】——单例模式(Singleton Pattern)

单例模式(Singleton Pattern)是这些设计模式中的一种,它提供了一种创建对象的最佳方式,确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。这种模式在需要严格控制资源访问、管理全局状态或实现共享资源访问时非常有用。

J^T的博客 4738

C++设计模式——单例模式(Singleton Pattern)

C++设计模式——单例模式(Singleton Pattern) 微信公众号:幼儿园的学霸 目录 文章目录C++设计模式——单例模式(Singleton Pattern)目录定义代码示例懒汉模式线程/内存不安全方式智能指针+双检锁模式和智能指针+call_once模式局部静态变量模式饿汉模式总结参考资料 定义 单例模式顾名思义,保证一个类仅可以有一个实例化对象,并且提供一个可以访问它的全局接口。实现单例模式必须注意一下几点: 单例类只能由一个实例化对象。 单例类必须自己提供一个实例化对象。 单例类必须

leonardohaig的博客 1467

设计模式:单件模式(5)C++版

单件模式:生成且仅生成类的一个实例。 C++示例代码如下: #include "stdafx.h" /* * CONTENTS: DESIGN PATTERN, SINGLETON PATTERN * AUTHOR: YAO H. WANG * TIME: 2013-11-1 23:16:05 * EDITION: 1 * * ALL RIGHTS RESERVED

Yao H. Wang's Blog 545

C++ 设计模式:单例模式(Singleton Pattern)

C++ 设计模式:单例模式(Singleton Pattern)

冀晓武的博客 922
上一篇: c++高级---C++ 类中特殊的成员变量(常变量、引用、静态)
下一篇: c++ Lib Dll及相关头文件关系和怎么操作
HNFXS985
博客等级 码龄14年 219粉丝 150原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值