单例九品--第二品

单例九品--第二品

  • 第一品回顾
  • 写在前边
  • 代码部分
  • 实现方式评注与思考
  • 下一品设计的思考

第一品回顾

第一品传送门
第一品的实现方式完全没有阻止构建类的多个对象,在这一品中将会修复这种问题。

写在前边

  • 基本思路
    • 将构造、析构函数设置为私有成员
    • 使用静态成员函数获取唯一的实例
  • 优点
    • 可以防止用户不小心构造新的实例
    • (C++11 开始)系统会保证函数内部的静态成员初始化是多线程安全的
  • 特点
    • 缓式初始化(lazy initialization)
  • 缺点
    • 没有完全阻止用户构造该类的多个对象

代码部分

两个文件, mian.cpp和sing.h

  • mian.cpp
#include "sing.h"int main(int argc, char** argv)
{std::cout << "get value: " << Sing::Instance().val << '\n';return 0;
}
  • sing.h
#pragma once
#include <iostream>class Sing
{
public:static const Sing& Instance(){static Sing inst;return inst;}
private:Sing(){std::cout << "Sing construct\n";val = 100;}~Sing(){std::cout << "Sing destroy\n";}public:int val;
};
  • output
    gcc编译运行结果:
    命令:
    gcc -c main.cpp -std=c++20
    g++ -c main.o -o ./m
    ./m
get value: Sing construct
100
Sing destroy

实现方式评注与思考

  1. 构造instance接口来构造唯一实例的全局访问点,并将构造函数和析构函数写为私有,这样只能通过全局访问点instance来完成实例的构造和访问。一定程度上有效减少了在翻译单元中不小心使用(Sing sing1;)的方式定义对象的问题。
  2. 用static关键字修饰instance函数为了不实例化对象可以直接调用instance函数。
  3. 单例对象inst定义为static,是因为在首次访问全局访问点instance完成单例构造以后,这个单例将会在整个程序周期存在
  4. C++11标准以后规定,这种写法即便是单线程多次调用instance函数,还是多线程同时访问instance函数。全局单例对象inst只在istance首次被访问的时候构建,所以不会出现多次定义的情况。 即便是多个线程同时都去访问全局访问点,也不会造成实例的多次构造。所以系统会保证函数内部的静态成员初始化是多线程安全
  5. 这种写法,单例对象在第一次使用时才会完成构建,并不是第一品实现的那样,在使用前就已经完成了构造,也就是"缓释初始化"。缓释初始化会对第一个用户不太友好,如果初始化逻辑比较复杂,极端情况下,可能会有一定的耗时。
  6. 这种写法,第二品的设计思路可以一定程度上减少用户不小心完成多次对象定义的问题,但是没有完全阻止用户构造该类的多个对象
    比如将main.cpp写为下边这样:
#include "sing.h"int main(int argc, char** argv)
{std::cout << "get value: " << Sing::Instance().val << '\n';Sing* sing2 = new Sing(Sing::Instance());return 0;
}    

这种设计方式,没有完全阻止用户构造该类的多个对象, 因为没有完成限制拷贝构造函数的权限。对于没有定义拷贝构造函数的类,在编译期会合成一个缺省的拷贝构造函数,这个函数是public的。所以Sing* sing2 = new Sing(Sing::Instance())使用拷贝构造函数完成了堆上的一个对象的建立,实现了全局访问对象inst到堆上对象sing2的赋值。并且因为堆内存的释放,需要显式的完成,不用调用析构函数(这里写的是private)的需求,因此工程是可以完成编译运行的。

下一品设计的思考

下一品将进行拷贝,移动构造函数的限制。已达到完全限制用户用户构造该类的多个对象。

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

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

相关文章

ES: ES+Kibana 环境部署

ESKibana 部署 机器信息 10.10.8.62 10.10.8.63 10.10.8.64版本选择&#xff1a;6.8.1 基础环境优化 所有节点 # 关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service# 查看selinux getenforce # 关闭selinux setenforce 0 # 永久关闭se…

取证工作:如何解锁受密码保护的 SQL Server 数据库并重置密码?

Advanced SQL Password Recovery 是 Elcomsoft 取证工具包中的密码破解软件之一。该软件可以即时访问受密码保护的 SQL Server 数据库。更改以 Microsoft SQL Server 格式保护数据库的任何用户或管理密码。 即时重置密码以保护 Microsoft SQL Server 数据库任何语言和编码的密…

浅谈碳化硅MOSFET TO-247封装单管引入开尔文管脚必要性

相较于传统的硅MOSFET和硅IGBT 产品&#xff0c;基于宽禁带碳化硅材料设计的碳化硅 MOSFET 具有耐压高、导通电阻低&#xff0c;开关损耗小的特点&#xff0c;可降低器件损耗、减小产品尺寸&#xff0c;从而提升系统效率。而在实际应用中&#xff0c;我们发现&#xff1a;带辅助…

外包干了一个月,技术退步明显。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 这次来聊一个大家可能也比较关心的问题&#xff0c;那就是就业城…

Sora的双重边缘:视频生成的革新与就业的再思考

随着科技的日新月异&#xff0c;人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术如潮水般涌入我们的日常生活&#xff0c;为各个领域带来了翻天覆地的变化。在这一浪潮中&#xff0c;Sora作为一款前沿的AI视频生成工具&#xff0c;凭借其高度逼真…

MindOpt优化器: 浅谈版本0.x和1.x之间API的差异

Mindopt 是一个优化求解器&#xff0c;如果它有两个主要版本——0.xx和1.x.x&#xff08;最新版本1.1.1&#xff09;&#xff0c;它们代表着软件开发的两个不同阶段。版本1.0.0表示软件的一个大的里程碑&#xff0c;代表着软件第一个正式的“成熟”发布版本&#xff0c;而0.25是…

MySQL--优化(索引--索引失效场景)

MySQL–优化&#xff08;索引–索引失效场景&#xff09; 定位慢查询SQL执行计划索引 存储引擎索引底层数据结构聚簇和非聚簇索引索引创建原则索引失效场景 SQL优化经验 常见的索引失效场景 1、场景准备&#xff1a; 给 tb_user 表创建联合索引&#xff0c;字段为&#xff1…

SSR和CSR

SSR&#xff1a;服务端渲染&#xff08;Server-Side Rendering&#xff09; 浏览器每次请求时&#xff0c;服务端都会生成页面完整的HTML响应&#xff0c;最后在浏览器将静态的HTML“激活”。 CSR&#xff1a;客户端渲染&#xff08;Client-Side Rendering&#xff09; 首次…

消息队列-Kafka-消费方如何分区与分区重平衡

消费分区 资料来源于网络 消费者订阅的入口&#xff1a;KafkaConsumer#subscribe 消费者消费的入口&#xff1a;KafkaConsumer#poll 处理流程&#xff1a; 对元数据重平衡处理&#xff1a;KafkaConsumer#updateAssignmentMetadataIfNeeded 协调器的拉取处理&#xff1a;onsum…

linux下改变主机名,永久生效的方法

hostnamectl set-hostname test 例子 #支持大写必须就要这样写 hostnamectl set-hostname 名称 --static

缩放算法优化步骤详解

添加链接描述 背景 假设数据存放在在unsigned char* m_pData 里面&#xff0c;宽和高分别是&#xff1a;m_nDataWidth m_nDataHeight 给定缩放比例&#xff1a;fXZoom fYZoom&#xff0c;返回缩放后的unsigned char* dataZoom 这里采用最简单的缩放算法即&#xff1a; 根据比…

每天一个数据分析题(一百九十五)

关于用户标签的分类&#xff0c;下列哪些说法是正确的&#xff1f; A. 属性标签主要包括用户的个人信息&#xff0c;如性别和出生日期&#xff0c;这些数据虽无因果关系&#xff0c;但可以用于预测用户行为。 B. 状态标签反映的是用户的社会经济状态和社会资本&#xff0c;如…

PostgreSQL教程(二十四):服务器管理(六)之数据库角色

PostgreSQL使用角色的概念管理数据库访问权限。一个角色可以被看成是一个数据库用户或者是一个数据库用户组&#xff0c;这取决于角色被怎样设置。角色可以拥有数据库对象&#xff08;例如&#xff0c;表和函数&#xff09;并且能够把那些对象上的权限赋予给其他角色来控制谁能…

代理IP以及动态拨号VPS的关系是什么?

在数字时代&#xff0c;网络安全和隐私保护已成为全球关注的热点话题。代理IP和动态拨号VPS作为提升网络匿名性和安全的重要技术&#xff0c;它们在维护网络隐私中扮演着至关重要的角色。虽然这两种技术在表面上看似相似&#xff0c;实际上它们在功能、应用场景以及用户需求满足…

react + antdesign table组件合并行,展开子表格

假如你有这样的一个数据&#xff1a; [{"bigClass":"吃的","smallClass":"水果","item":"苹果"},{"bigClass":"吃的","smallClass":"水果","item":"香蕉…

mutex 和 channel 哪一个工作效率更高?

关于Rust中mutex和channel哪一个工作效率更高的问题&#xff0c;实际上并没有一个绝对的答案&#xff0c;因为效率的高低取决于具体的使用场景和需求。 互斥锁&#xff08;mutex&#xff09;主要用于保护共享资源&#xff0c;确保一次只有一个线程可以访问它。当需要多个线程同…

这些养老难题,只能靠AI来解决了

3 月 5 日刚召开的两会&#xff0c;AI 这个话题妥妥站上了 C 位。不仅政府工作报告首次提出要开展“人工智能”行动&#xff0c;各路科技大佬和人大代表也是围绕着 AI 大模型的技术创新、应用落地和政策法规&#xff0c;展开了热烈积极的建言献策。甚至有互联网大佬建议将人工智…

创建RAID0,RAID5并管理,热备盘,模拟故障

目录 1. RAID介绍以及mdadm安装 1.1 安装mdadm工具 2. 创建raid0 2.1 环境准备 2.2 使用两个磁盘创建RAID0 2.3 查看RAID0信息 2.4 对创建的RAID0进行格式化并挂载 2.5 设置成开机挂载 2.6 删除RAID0 3. 创建raid5 3.1 环境准备 3.2 用3个磁盘来模拟R…

2024-01 STEMA 考试C++ 中级真题解析

2024-01 STEMA 考试C++ 中级真题一、选择题 第一题、表达式117 % 16 的结果是( B )。 A、0 B、5 C、7 D、10第二题、下列选项中,字符数组定义正确的是(B )。 A、char a[5] = "hello"; B、char a[ ] = "hello"; …

Go微服务: 基于net/rpc/jsonrpc模块实现微服务跨语言调用

概述 Golang 提供 net/rpc/jsonrpc 库来实现rpc方法采用 json 方式进行数据编解码&#xff0c;支持跨语言调用 这里实现跨语言示例 1 &#xff09;go 服务端 package main import ( "log" "net" "net/rpc" "net/rpc/jsonrpc" )…