C++实现单例模式及遇到的问题

C++单例模式Http管理者实战:从设计原理到全栈聊天应用集成 在C++网络编程中,设计模式是构建可维护、高效软件架构的核心工具。单例模式作为一种创建型模式,通过确保一个类仅有一个实例并提供全局访问点,有效解决了资源重复创建和统一管理的问题。其技术价值在于优化内存使用、简化全局状态访问,并便于实现集中式的配置与行为控制。在工程实践中,单例模式广泛应用于日志系统、配置管理、连接池以及网络请求管理等场景。本文聚焦于**Http管理者**的设计与实现,深入探讨了在C++中如何结合**Meyers' Singleton**这一线程安全方案,构建一个健壮的中心化HTTP客户端,并 阅读详情

通常而言,单例模式分为三种实现方式:

  1. 懒汉式:系统定义实例。
  2. 饿汉式:直接给用户定义一个实例,以后都是直接调用这个。
  3. 双重检验:通常用于多线程时线程安全的代码。

首先,展示一个错误的代码示范:(C++11)

class Singleton{
    public:
    static Singleton getInstance(){
        if(single) return single;
        else 
            single = new Singleton();
        
        cout<<"ADDR: "<<&single<<endl; // 对象,用取地址符输出地址,用于比较是否为同一个实例
        return single;
    }
    
    private:
    static Singleton single;
    Singleton()=default;
    ~Singleton()=default;
}

对于初学者来说,咋一看可能没觉得有问题,其实有两个严重问题,如下:

 问题1: 

 if(single) return single

编译器会告诉你: 

could not convert ‘Singleton::single’ from ‘Singleton’ to ‘bool’

一般人会认为,对象没创建时肯定是空,也就是bool类型的false,好像可以用if直接判断。 显然编译器已经告诉了我们答案:绝对不可以!

 准确来说,Singleton::single是一个未识别的类型,因为是你自己定义的,除非你自己通过重载运算符之类的定义了隐式转换,否则,编译器无法为你进行隐式转换成bool类型。

问题2:

            single = new Singleton();

new产生一个新的对象,返回的不是新的对象!而是指向这个新对像的指针!

可以看一下new的底层调用形式:

void * operator new(size_t size)

很明显,返回的是指针。所以,用来接收收新对象时须定义一个指针。

补充:

  • 这里使用static修饰实例对象是因为,单例,即这个类只能存在这一个实例,显然,static符合。
  • 把构造函数和析构函数私有化,就是为了防止用户直接调用构造函数,破坏单例。

下面,开始贴上正确代码:

1. 懒汉式

#include <iostream>

using namespace std;

class Singleton{
    public:
    static Singleton* getInstance(){
        if(single== nullptr)  
            single = new Singleton();
        
        cout<<"ADDR: "<<single<<endl;  // &single替换成single,因为single本身存的就是地址了
        return single;
    }
    
    private:
    static Singleton *single;
    Singleton()=default;
    ~Singleton()=default;
};
 Singleton* Singleton::single = nullptr;
int main()
{
   Singleton* s;
   s->getInstance();
   Singleton* s2;
   s2->getInstance();
   Singleton* s3;
   s3->getInstance();
   return 0;
}

输出:

$g++ -std=c++11 -o main *.cpp
$main
ADDR: 0x601178
ADDR: 0x601178
ADDR: 0x601178

2. 饿汉式

#include <iostream>

using namespace std;

class Singleton{
    public:
    static Singleton* getInstance(){
        if(single== nullptr)  
            single = new Singleton();
        
        cout<<"ADDR: "<<single<<endl;
        return single;
    }
    void destroy(){
        cout<<"Invoke deconstructor."<<endl;
        delete single; //销毁对象,但指针仍指着那块地址。
        single = nullptr; //重置指针
    }
    
    private:
    static Singleton *single;
    Singleton()=default;
    ~Singleton()=default;
};
 Singleton* Singleton::single = new Singleton() ; // 直接实例化
int main()
{
   Singleton* s=Singleton::getInstance();
   s->destroy();

   Singleton* s2=Singleton::getInstance();
   s2->destroy();

   Singleton* s3=Singleton::getInstance();
   
   return 0;
}

对应的输出:

$g++ -std=c++11 -o main *.cpp
$main
ADDR: 0x991c20
Invoke deconstructor.
ADDR: 0x991c20
Invoke deconstructor.
ADDR: 0x991c20

3. 双重校验--用于多线程甚至多进程环境。

#include <iostream>
#include<pthread.h>
using namespace std;
class Singleton{
    public:
    static Singleton* getInstance(){
        if(single== nullptr)  {
            pthread_mutex_lock(&mutex_);
            if(single== nullptr)
                 single = new Singleton();
            pthread_mutex_unlock(&mutex_);
        }
        cout<<"ADDR: "<<single<<endl;
        return single;
    }
    void destroy(){
        cout<<"Invoke deconstructor."<<endl;
        delete single; //销毁对象,但指针仍指着那块地址。
        single = nullptr; //重置指针
    }
    
    private:
    static Singleton *single;
    static pthread_mutex_t mutex_;
    Singleton()=default;
    ~Singleton()=default;
};
 Singleton* Singleton::single = nullptr ; // 直接实例化
 pthread_mutex_t Singleton::mutex_;
 void gg(){
     Singleton::getInstance();
 }
int main()
{
   
    pthread_t p1,p2;
    pthread_create (&p1,NULL,gg,NULL);
    pthread_create (&p2,NULL,gg,NULL);
   
   return 0;
}

作为进一步补充,可以参考一下网友的C++完美单例模式。

别再手动建模了!用Simscape Multibody Link一键导入SolidWorks装配体到Simulink 本文介绍了如何利用Simscape Multibody Link插件将SolidWorks装配体一键导入Simulink,实现CAD到仿真的无缝衔接。该技术显著提升机械系统设计与控制效率,特别适用于工业机器人、车辆悬架等复杂机构的动力学分析。文章详细解析了插件安装、模型导出优化及仿真验证的全流程,帮助工程师摆脱手动建模的低效工作模式。 阅读详情

相关推荐

Word公式一键转MathType保姆级教程(附omml2mml.xsl报错终极解决方案)

本文提供Word公式一键转MathType的保姆级教程,重点解决常见的omml2mml.xsl报错问题。通过详细分析报错原因、官方解决方案实操步骤及转换后格式优化技巧,帮助用户高效完成公式转换,适用于科研论文和商业文档编辑。

weixin_30082367的博客 566

面试官:你写的单例模式有空指针异常,请你用Volatile改一下。我愣了五分钟

欢迎关注公众号【JAVA前线】查看精彩文章 1 单例模式 大家对单例模式并不会陌生,当创建一个对象需要消耗比较多资源时,例如创建数据库连接和消息服务端等等,这时我们选择只创建一份这种类型的对象并在进程内共享。 但是单例模式想要写好并不容易,我们写多个版本的单例模式看看每个版本都有什么问题。 1.1 版本一 这个版本问题非常明显:getConnection方法中多个线程可能同时执行到语句1,而此时myConnection都为空,造成连接对象被多次创建。 public class MySimpleConn.

JAVA前线技术专栏 1100

TCP协议中ARQ自动重传的三种实现方式对比(含SACK详解)

本文深入解析TCP协议中ARQ自动重传的三种实现方式,包括停止-等待、回退N步和选择重传协议,特别详细介绍了SACK机制的工作原理和优势。通过对比分析各协议的效率、复杂度和适用场景,为网络通信中的可靠性传输提供了实用的选型指南。

weixin_30776273的博客 462

单例模式返回值为空(空指针异常)

单例模式返回值为空(空指针异常)空指针异常 空指针异常 今天使用单例模式返回一个 Statement对象 的时候,发现总是报空指针异常,经过我仔细检查,发现是对 Statement变量 的定义写在了类实例化语句的后面!当类实例化的时候,不能把目标对象的引用正确赋值给我声明的变量。我把变量声明写在实例化之前,再运行:NullPointerException——解决了! ...

Green__Hand__的博客 2002

避坑指南:C#调用CodeSoft打印标签时常见的5个错误及解决方法

本文总结了C#调用CodeSoft打印标签时常见的5个核心错误及解决方案,涵盖环境配置、模板加载、变量赋值、打印机切换和资源管理。重点解析了如何避免COM对象创建失败、模板路径错误、变量名不匹配、打印机切换异常及内存泄漏等问题,帮助开发者实现稳定高效的标签打印集成。

weixin_29215815的博客 233

MySQL 一一 MySQL基本使用

1、数据库 简单来说,所谓的数据库就是存储数据的容器,而且是永久存储的。 2、为什么需要数据库 3、为什么要学习MySQL数据库 最早MySQL数据,瑞典AB公司开发的一款开源型的关系型数据库。 随着时间的推移,瑞典AB公司把MySQL数据库转让给Sun公司(Java语言的创始公司) 后来,Sun公司经营不善,又把MySQL数据库转让给甲骨文公司(Oracle数据库) 4、数

Guizy 7万+

设计模式(二):单例模式

单例模式C++

supermario19的博客 382

智能园艺:AI Agent控制的室内种植系统

随着城市化进程的加速和人们对健康生活的追求,室内种植逐渐成为一种流行的生活方式。然而,传统的室内种植方式往往需要人工进行大量的监测和管理,效率低下且难以保证植物的生长质量。智能园艺:AI Agent控制的室内种植系统旨在利用先进的人工智能技术和传感器设备,实现室内种植的自动化和智能化管理,提高种植效率和植物生长质量。本系统的范围涵盖了从植物生长环境的监测到种植过程的自动化控制,包括温度、湿度、光照、土壤水分等环境参数的实时监测,以及灌溉、施肥、通风等种植操作的自动执行。

AI天才研究院 784

C++单例模式模板 (简单易懂且有效)

单例模式几乎是最常用的设计模式,简单易懂,使用起来效果显著,在此也不对单例模式做剖析,不了解的可以自行查阅资料。 项目中多次使用单例模式后发现每次都是重复的构建单例类,于是做了一个单例模式的模板。 //单例模板 //delete 与 default 来自于 c++ 11 template <typename T> class Singleton { //使用默认构造和析构函数 Singleton() = default; ~Singleton() = default; p

为啥不吃肉捏 的博客 5318

【24届数字IC秋招总结】笔试面试篇——投递公司及时间节点汇总

从实习、提前批到秋招投递的有进展的公司进行汇总,关于各个公司的笔试和面试经历详见其他帖子。

qq_42135020的博客 1923

VTK:受约束的 Delaunay 2D用法实战

VTK:受约束的 Delaunay 2D用法实战程序输出程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkCellArray.h> #include <vtkDelaunay2D.h> #include <vtkMath.h> #include <vtkMinimalStandardRandomSequence.h> #include <vtkNamedColors.h>

希望我的博客,能帮上你解决学习中工作中所遇到的问题 948

c++ 中单例模式不生效问题分析

1.现象描述 代码中使用static类型单例,但是获取了多次该单例的实例发现其每次获取的实例的地址都不一样 2.问题解决 其中调用的链接库存在静态和动态版本,统一改为动态库后问题解决

lab1228的博客 698

基于 transformer、lstm、LSTM多特征的交通流量预测 完整数据代码 超全项目 本科硕士毕设卓卓有余

基于 transformer、lstm、LSTM多特征的交通流量预测 完整数据代码 超全项目 本科硕士毕设卓卓有余

4657

c++中单例模式的实现和问题

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

reedthink的博客 646

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

关于C++实现单例模式的一些堆栈作用域的小问题

前几天晚上,给公司做机器人导航的舒少讲了几个常用的设计模式,主要是创建类型的工厂、建造者之类的。昨天晚上临下班他找我问了一个关于C++单例模式的一个问题。 问题是这同样的: 他看了一篇文章,里面实现了饿汉模式的单例,将构造函数私有化,提供公开静态的GetInstance()方法。这都毫无疑问,作者是这样写的代码。 #pragma once class Singelton { private: static Singelton *single; static Singelton single

生活不止眼前的苟且 476

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C++单例模式实现及可能的问题

参考:http://blog.cnbang.net/tech/2229/

Arcsinsin的学习笔记 753

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C++ VS单例模式报 错误 LNK2001 无法解析的外部符号 private: static class SingletonPattern错误

一、前言 如图所示,C++使用VS写完单例模式后,报如下错误: 错误 LNK2001 无法解析的外部符号 “private: static class SingletonPattern * SingletonPattern::m_Instance” (?m_Instance@SingletonPattern@@0PAV1@A) Test 错误 LNK1120 1 个无法解析的外部命令 二、代码 2.1 SingletonPattern.h #pragma once #include <ios

LyRics1996的博客 2878

C++单例模式的n种实现总结

面试官:“接下来,说说C++实现一个单例模式的思路吧”。 这个问题我曾经看过,舒了一口气,冷静了一下缓缓答道:“所谓单例模式,就是一个类在程序的过程中只能有一个实例对象,不能随意的创建对象实例,因此,首先就是要把构造函数设置为private,这样用户代码无法创建一个对象,还对象只能在类内创建。” 面试官:“嗯,然后呢?” 我:“同时还要定义一个public+static函数接口,供外部访问该对象,...

每天完成一个小目标 559

C++单例模式跨DLL调用问题梳理

假设有这样一个单例模式的代码接下来分别调用它们运行后得到结果居然得到了不一样的地址,说明这种方法实现单例会发生意料之外的问题。

m0_47666995的博客 887

C++单例模式

先简单介绍一下单例模式:单例模式(Singletion Pattern)是一种软件开发中的设计模式,属于创建型模式(也称工厂模式,封装对象的创建过程,使客户端可以透明地创建对象,而不需要关心对象的内部实现细节)。单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。单例模式通常用于管理共享资源,如文件系统、硬件设备等,或者在。

github_35852648的博客 1143

【设计模式学习笔记】单例模式详解(懒汉式遇上多线程问题解析基于C++实现)

单例模式主要有懒汉式和饿汉式两种实现,饿汉式不会有线程安全的问题,但是提前构造对象占用了一定的资源,如果对内存要求较低的场景可以使用饿汉式实现;懒汉式应使用DCL机制来避免多线程竞争资源的问题,并且懒汉式可以在需要使用对象的时候才去创建对象,节省了资源。

仅以此博客记录日常学习工作中所思所得,水平有限,难登大雅,万望海涵。 1253

《C++20设计模式》学习笔记---单例模式

单例模式并不完全令人厌恶,但是,如果不小心使用,它们会破坏应用程序的可测试性可可重构性。如果必须使用单例模式,请尝试避免直接使用它(如编写SomeComponent.get().foo()),将其指定为依赖项(例如,作为构造函数的参数),并保证所有依赖项都是从应用程序的某个唯一的位置(例如,控制反转容器)获取或初始化的。

BirdsLife的博客 1631

C++单利模式常见问题

C++语言是一门具有面向对象的高性能语言,其执行效率不小于C语言的80%。所以在现在的深度学习中被广泛使用,深度学习在跑的实例需要大量的计算资源,算法在实现上又要实现模型的抽象。综合考虑,C++是其载体的不二之选,模型验证可以使用更加方便的python等高级语言,方便修改和编写简单。实际在工程中使用的还是以C++作为模型的载体来实现算法。 C++是一门结合高性能和具有面向对象抽象的语言,同比其他...

a1a38181的博客 381

c++ 单例模式

1. 什么是单例模式 单例模式(Singleton Pattern,也称为单件模式),使用最广泛的设计模式之一。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。 定义一个单例类: 私有化它的构造函数,以防止外界创建单例类的对象; 使用类的私有静态指针变量指向类的唯一实例; 使用一个公有的静态方法获取该实例。 2. 懒汉版(Lazy Singleton) 教学版,即懒汉版(Lazy Singleton):单例实例在第一次被使用时才进行初始化,这叫做延迟初

帅的没拼音 2万+

C++_单例模式

在C++中有许多设计模式,单例模式就是其中的一种,该模式主要针对类而设计,确保在一个进程下该类只能实例化出一个对象,因此名为单例。而单例模式又分为饿汉方式和懒汉方式,饿汉方式指的是只要发出了对该类的需求,就会实例化对象。懒汉方式指的是即使发出了对该类的需求,但是不会立刻实例化对象,等到真正用到该对象时才会实例化对象。

安权_code的博客 4416

单例模式 C++

懒汉,饿汉,解决内存泄漏,双检锁,原子,C++11 magic static,模板类

IT OR 考公? 2207
上一篇: 电脑定时开关机
下一篇: 高效计算N次方
Poo_Chai
博客等级 码龄9年 178粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Poo_Chai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值