C++单例模式(三种方式)

  单例模式实现要点:

  1. 构造函数私有化 - 为避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
  2. 类中创建一个本类对象 - 本类中自定义对象,让其他程序可以访问
  3. 提供方法获取到该对象 - 方便其他程序对自定义对象的访问 

 单例模式实现方式: 

 1.懒汉式(多线程不安全) - 需要时才进行实例化

#include<iostream>
using namespace std;
#include <windows.h>//核心的本质就是,只能实例化一个实体
class Singleton {
private:Singleton() {}Singleton(Singleton&) = delete; //禁止使用Singleton& operator=(const Singleton&object) = delete;  //禁止使用public:~Singleton() {}//获取一个实例static Singleton* getInstance() {//如果指针为空,则重新创造一个实例if (m_instance_ptr == nullptr) {m_instance_ptr = new Singleton;}//否则,说明已经创建过了,直接返回return m_instance_ptr;}void func(){cout << "成功实例化了!!!" << endl;}
private:static Singleton* m_instance_ptr;
};Singleton* Singleton::m_instance_ptr = nullptr;//在外部对指针进行初始化int main() {static Singleton* instance = Singleton::getInstance();instance->func();system("pause");return 0;
}

问题1:static Singleton* m_instance_ptr; 中的static有什么作用

在这个代码中,static关键字用于声明m_instance_ptr成员变量为静态变量。静态变量是属于类而不是类的实例的变量,因此在整个程序运行期间只会有一个m_instance_ptr变量的实例。这使得在getInstance()方法中可以对该变量进行检查,确保只创建一个Singleton类的实例。

问题2: c++ static是不是就只有一份数据,每次操作都会直接作用在本体上

 是的,C++中的静态数据成员只有一份数据,不会随着对象的创建而分配新的内存空间。每次操作都会直接作用在这份数据上,不会因为对象的创建而产生新的副本。因此,静态数据成员可以被所有对象共享,并且可以在不创建对象的情况下直接访问和修改。

2.懒汉式(多线程安全)-进行加锁 

#include <iostream>
#include <memory> // shared_ptr
#include <mutex>  // mutexclass Singleton {
public:typedef std::shared_ptr<Singleton> Ptr;~Singleton() {std::cout << "析构函数!!!" << std::endl;}Singleton(Singleton&) = delete; //禁止使用Singleton& operator=(const Singleton&) = delete;  //禁止使用static Ptr getInstance() {if (m_instance_ptr == nullptr) {std::lock_guard<std::mutex> auto_lock(m_mutex);if (m_instance_ptr == nullptr) {m_instance_ptr = std::shared_ptr<Singleton>(new Singleton);}}return m_instance_ptr;}void use() const {std::cout << "已经成功初始化了" << std::endl;}private:Singleton() {}static Ptr m_instance_ptr;static std::mutex m_mutex;
};
Singleton::Ptr Singleton::m_instance_ptr = nullptr;
std::mutex Singleton::m_mutex;int main() {Singleton::Ptr instance = Singleton::getInstance();instance->use();system("pause");return 0;
}

问题1:shared_ptr<Singleton>有什么作用

使用std::shared_ptr<Singleton>可以确保在程序中只有一个实例对象,并且可以方便地在需要时访问该实例对象。std::shared_ptr是智能指针的一种,它可以自动管理对象的生命周期,确保在不再需要时正确地释放对象,避免内存泄漏。在这个示例中,std::shared_ptr<Singleton>确保了只有一个Singleton对象实例,并且在程序结束时正确地释放该实例对象。

问题2: 上面的代码加锁了,难道不用解锁吗

 在上面的代码示例中,确实在获取单例对象实例时使用了std::lock_guard<std::mutex>来加锁,但是没有显式地解锁。这是因为std::lock_guard是一个RAII(资源获取即初始化)类,它在构造时会自动锁住互斥量,在析构时会自动释放锁,即在作用域结束时会自动解锁。

因此,在上面的代码中,当std::lock_guard<std::mutex>对象auto_lock超出作用域时,会自动调用析构函数,从而释放锁,不需要显式地调用解锁操作。这样可以确保在任何情况下都能正确释放锁,避免忘记解锁而导致的死锁问题。

问题3:静态变量都需要在类外进行初始化吗? 

 在C++中,静态成员变量必须在类外进行定义和初始化。这是因为静态成员变量是属于类的,而不是属于类的实例,因此需要在类外进行定义和初始化。

在上面的代码中,singleton::ptrsingleton::m_mutex都是singleton类的静态成员变量,因此需要在类外进行初始化。静态成员变量的初始化必须在全局作用域进行,以确保在程序运行之前就完成了初始化。

通过在全局作用域进行初始化,确保了静态成员变量在程序运行时已经被正确初始化,可以在类的静态成员函数或其他地方使用这些静态成员变量。

问题4: NULL和nullptr有什么区别

 NULLnullptr是C++中用于表示空指针的关键字,它们在一些方面有一些区别:

  1. NULL是在C语言中定义的宏,通常被定义为0或者(void*)0。在C++中,NULL通常被定义为0。因此,NULL实际上是一个整数值的常量。

  2. nullptr是C++11引入的关键字,用于表示空指针常量。nullptr是一个特殊的空指针值,不是整数类型,而是属于nullptr_t类型。因此,nullptr可以更好地表示空指针,避免了一些潜在的问题。

  3. 在C++11及以后的标准中,推荐使用nullptr来表示空指针,而不是NULL。因为nullptr具有更好的类型安全性,可以避免一些潜在的类型转换问题。

综上所述,nullptr是C++11引入的更安全和更明确的表示空指针的关键字,推荐在新的C++代码中使用nullptr来表示空指针。而NULL仍然可以在一些老的代码中使用,但最好在新代码中使用nullptr

 3.饿汉式-提前实例化

#include <iostream>class Singleton {
public:~Singleton() {std::cout << "析构函数!!!" << std::endl;}Singleton(Singleton&) = delete; //禁止使用Singleton& operator=(const Singleton&) = delete;  //禁止使用static Singleton* getInstance() {return m_instance;}void use() const {std::cout << "已经实例化对象了!!!" << std::endl;}private:Singleton() {}static Singleton* m_instance;};//直接在外部就只实例化一个对象,避免的多创建的风险
Singleton* Singleton::m_instance = new Singleton;int main() {Singleton* instance = Singleton::getInstance();instance->use();system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/11366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java并发编程——相关基础概念

Java并发编程是Java中处理多个任务同时执行的能力。在构建高性能、可扩展和响应性良好的系统时&#xff0c;并发编程是非常关键的。以下是Java并发编程中的一些基础概念&#xff1a; 线程&#xff08;Thread&#xff09;&#xff1a; 线程是操作系统调度的最小单位&#xff0c;…

【强训笔记】day21

NO.1 思路&#xff1a;第一个位置放最小的&#xff0c;其次放最大的&#xff0c;依次类推。 代码实现&#xff1a; #include<iostream>using namespace std; int n;int main() {cin>>n;int left1,rightn;while(left<right){cout<<left<<" &…

Nios-II编程

文章目录 一硬件部分设计1Qsys2Quartus 二软件1Nios-II Eclipse 三运行项目及效果1配置 FPGA 一硬件部分设计 1Qsys 1创建一个项目 2点击 Tools 下拉菜单下的 Platform Designer 工具&#xff0c;启动 Platform Designer 后&#xff0c;点击 File-save&#xff0c;在文件名中…

2024年华为OD机试真题- 求字符串中所有整数的最小和-Java-OD统一考试(C卷D卷)

题目描述: 输入字符串s,输出s中包含所有整数的最小和 说明 1. 字符串s,只包含 a-z A-Z +- ; 2. 合法的整数包括 1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102 2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023 输入描述: 包含…

云原生基础设施和操作系统分论坛 03-在Kubernetes上运行Apache Spark进行大规模数据处理的实践【数据分析】

https://spark.apache.org/视频观看&#xff1a;https://www.bilibili.com/video/BV17J4m1n7Gv/?spm_id_from333.999.0.0 简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室)所开源的类Hadoop…

SpringBoot项目中基于PDF模板生成PDF文档

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525; 微…

kong 网关 docker 安装3.4

kong 安装 docker network create kong-net安装postgres 9.6 本版很重要 高版本 安装konga 初始化会有问题 docker run -d --name kong-database \--network=kong-net \-p 5432:5432 \-e "POSTGRES_USER=kong" \-e "POSTGRES_DB=kong" \-e "POSTGRE…

uniapp push个推在线和离线消息监听,离线消息intent参数设置和获取,java后端推送

uniapp push 1.0版本 我用华为手机测试的离线消息&#xff0c;首先要保证在华为后台推送消息&#xff0c;uniapp离线打包的app能收到。 java后端推送 pom.xml依赖 <dependency><groupId>com.getui.push</groupId><artifactId>restful-sdk</artifac…

Java入门基础学习笔记20——三元运算符、运算符优先级

1、三元运算符介绍&#xff1a; 格式&#xff1a; 条件表达式 ? 值1: 值2 执行流程&#xff1a;首先计算关系表达式的值&#xff0c;如果值为true&#xff0c;就返回值1&#xff0c;如果值为false&#xff0c;就返回值2。 例1&#xff1a; package cn.ensource.operator;p…

企业级WEB服务Nginx安装

企业级WEB服务Nginx安装 1. Nginx版本和安装方式 Mainline version 主要开发版本,一般为奇数版本号,比如1.19Stable version 当前最新稳定版,一般为偶数版本,如:1.20Legacy versions 旧的稳定版,一般为偶数版本,如:1.18Nginx安装可以使用yum或源码安装,但是推荐使用源码编译安…

深圳盐田某前沿研究所:OLED透明屏引领未来科技空间

产品&#xff1a;55寸OLED透明屏 项目时间&#xff1a;2024年04月 项目地点&#xff1a;深圳盐田 在科技日新月异的今天&#xff0c;前沿的研究机构不仅追求科研的突破&#xff0c;也在不断探索和尝试将最新科技融入其工作环境之中。深圳盐田的一家前沿研究所便是这一探索的先…

星戈瑞ICG-Dextran的生物相容性

ICG-Dextran的生物相容性是评估其在生物体内应用的重要因素之一。虽然ICG-Dextran在不同应用中可能会有不同的配方和性质&#xff0c;但总体来说&#xff0c;它通常具有良好的生物相容性&#xff0c;主要有以下几个方面&#xff1a; **低毒性&#xff1a;**ICG-Dextran的成分中…

基于u-blox M8L的车载惯性导航系统方案(Carplay Location 认证)

此贴准备记录《基于u-blox M8L的车载惯性导航系统方案&#xff08;Carplay Location 认证&#xff09;》&#xff0c;先调查下&#xff0c; 如果有需求我再继续写。

网工路由基础——路由加表选路原则

一、路由器的介绍 路由器的是实现网络互连&#xff0c;在不同网络之间转发数据单元的重要网络设备。 路由器主要工作在OSI 参考模型的第三层&#xff08;网络层 &#xff09;&#xff0c;路由器的主要任务就是为 经过路由器的每个数据帧寻找一条最佳传输路径&#xff0c;并将该…

快手蓝V商家电话采集软件操作教程

抖音作为全球最受欢迎的短视频平台之一&#xff0c;拥有庞大的用户基础。其中不乏拥有蓝V认证的大V用户&#xff0c;他们的手机号码对于一些市场营销人员来说是非常有价值的。但是&#xff0c;抖音并没有公开这些大V用户的手机号码&#xff0c;怎样采集到他们的手机号码呢&…

钉钉群直播回放保存下来方法

想要永久留存那些不容错过的钉钉群直播精华吗&#xff1f;你是否曾在群直播结束后急切地希望重温那些信息满载的讲解&#xff0c;或是那些激动人心的讨论时刻&#xff1f;现在&#xff0c;你不再需要担忧这些宝贵内容的丢失。这里&#xff0c;我们将带领你通过一些简单的步骤&a…

沃比得 DP16A 对数周期天线 100MHz~6GHz

沃比得DP16A对数周期天线该天线可用做超短波发射或接收天线&#xff0c;工作频率为 100MHz&#xff5e;6GHz。具 有频带宽&#xff0c;性能可靠&#xff0c;增益高等优点&#xff0c;是理想的无线电频谱管理、EMC 测试、电子对抗等领域 的定向接收、发射天线。 应用领域 ●…

搞懂Docker(八)- 多容器app

获取示例程序 示例程序 或者 示例程序 获取示例程序程序结构如下├── getting-started-app/ │ ├── package.json │ ├── README.md │ ├── spec/ │ ├── src/ │ └── yarn.lock多容器app 到目前为止,我们学的都是只包含一个容器的程序。但是现在,我们需要…

在线业务的常见全栈故障种类与定位手段

在线系统的稳定性和可靠性是企业数字化转型成功的关键。然而&#xff0c;由于云环境和系统演进的复杂性&#xff0c;故障的发生几乎不可避免。本系列文章将对在线系统可能遇到的全栈故障进行分类&#xff0c;并结合网上的案例分析&#xff0c;对比常规分析诊断手段与Originx推理…

美国空军高调展示首个AI战斗机!部长亲自试驾全程未干预,10万行代码试飞21次

【新智元导读】美军战斗机&#xff0c;能由AI完成自主空战了&#xff01;最近&#xff0c;美国空军部长Kendall亲自试驾了国防部正在研制的X-62A AI飞机。1小时的飞行过程中&#xff0c;Kendall全程未干预&#xff0c;所有动作都由AI自主完成。 最近&#xff0c;军事圈被这个消…