C++语法(26)--- 特殊类设计

C++语法(25)--- 异常与智能指针_哈里沃克的博客-CSDN博客icon-default.png?t=N6B9https://blog.csdn.net/m0_63488627/article/details/131537799?spm=1001.2014.3001.5501

 目录

1.特殊类设计

1.设计一个类,不能被拷贝

C++98

C++11

2.设计一个类,只能在堆上创建对象

1.封掉所有拷贝

C++98

C++11

2.封掉析构函数

3.设计一个类,只能在栈上创建对象

4.设计一个类,不能被继承

1.C++98

2.C++11 final

2.单例模式

1.设计模式

2.单例模式

1.饿汉模式

2.懒汉模式

3.单例对象释放问题


1.特殊类设计

1.设计一个类,不能被拷贝

C++98

将拷贝函数只声明不实现,并且放到私有处。(只不过,在类型内部调用另外的函数进行拷贝就没有办法防止了)

class CopyBan
{// ...
private:CopyBan(const CopyBan&);CopyBan& operator=(const CopyBan&);//...
};

C++11

在函数申明后面加入 =delete

class CopyBan
{// ...CopyBan(const CopyBan&)=delete;CopyBan& operator=(const CopyBan&)=delete;//...
};

2.设计一个类,只能在堆上创建对象

1.封掉所有拷贝

C++98

1.先将构造函数封死,这样就无法在栈上创造对象了。但是我们需要提供一个函数调用,使得其在堆上创造对象。

2.创造堆上的函数不能直接修饰,这样会出现逻辑谬论(即想要创造对象,需要调用函数;想要调用函数,需要先创造对象)。所以这里的解决方式是设置静态函数,不需要this指针,所以不需要生成所谓对象才能调用,可以直接调用。

3.特别注意,其实拷贝构造函数也需要被处理一下,因为如果在外部先构造堆上的,随后通过解指针调用给拷贝构造,那么其实也是不算合格的。

class HeapOnly
{
public:static HeapOnly* CreateObject(){return new HeapOnly;}
private:HeapOnly() {}HeapOnly(const HeapOnly&) {}
}int main()
{HeapOnly* php = HeapOnly::CreateObject();
}

C++11

class HeapOnly
{
public:static HeapOnly* CreateObject(){return new HeapOnly;}HeapOnly(const HeapOnly&) = delete;HeapOnly(const HeapOnly&)  = delete;
};

2.封掉析构函数

1.将析构函数封掉也能达到相同的效果,因为构造了就需要被析构,类型没有检查到可以析构就会报错。

2.此时堆上的类需要被释放掉,也需要重新构造一个destory函数,其类型是类型的指针,不可以是对象本身,因为这样就是手动调用析构函数了。只要调用destory就能释放堆上的空间。

3.设计一个类,只能在栈上创建对象

这样设计使得不能创建在堆和静态上。

class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}
private:StackOnly():_a(0){}
private:int _a;
};

这样的设计使得不能在堆上创建但是,能产生静态的对象。

// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
void* operator new(size_t size) = delete;
void operator delete(void* p) = delete;

4.设计一个类,不能被继承

1.C++98

构造函数私有化,子类本来要调用父类的构造函数,没有则不能被继承。

class NonInherit
{
public:static NonInherit GetInstance(){return NonInherit();}
private:NonInherit(){}
};

2.C++11 final

class A final
{// ....
};

2.单例模式

1.设计模式

设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

一些设计理念:迭代器模式,配接器模式,单例模式,工厂模式,观察者模式

2.单例模式

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
使用样例:内存池的申请

1.饿汉模式

特点:

一开始(在main函数之前)就创造对象,就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象

缺点:

1.由于初始化在main函数之前,这样的类数据过多,会使得启动慢;

2.多个单例类有初始化依赖关系,饿汉模式无法控制类的初始化先后关系

class InfoSingleton
{
public:static InfoSingleton& GetInstance(){return _sins;}void Insert(string name, int money){_info[name] = money;}void Print(){for (auto kv : _info){cout << kv.first << " " << kv.second << endl;}}private:InfoSingleton(){}InfoSingleton(const InfoSingleton& info) = delete;InfoSingleton& operator=(const InfoSingleton& info) = delete;map<string, int> _info;private:static InfoSingleton _sins;
};InfoSingleton InfoSingleton::_sins;int main()
{InfoSingleton::GetInstance().Insert("张三", 1000);InfoSingleton& info = InfoSingleton::GetInstance();info.Insert("李四", 100);//InfoSingleton copy = InfoSingleton::GetInstance(); //拷贝构造//copy.Insert("***", 10000);return 0;
}

2.懒汉模式

1.如果单例对象构造十分耗时或者占用很多资源,比如加载插件啊, 初始化网络连接啊,读取文件啊等等,而有可能该对象程序运行时不会用到,那么也要在程序一开始就进行初始化,就会导致程序启动时非常的缓慢。 所以这种情况使用懒汉模式(延迟加载)更好。

2.如果类之间存在依赖关系,也可以使用懒汉模式(延迟加载)。

template<class Lock>
class LockGuard
{
public:LockGuard(Lock& lk):_lk(lk){_lk.lock();}~LockGuard(){_lk.unlock();}private:Lock& _lk;
};class _InfoSingleton
{
public://线程安全问题,多线程一起调用创建对象static _InfoSingleton& GetInstance(){//双检查增加效率if (_psins == nullptr) {LockGuard<mutex> lock(*_smtx);if (_psins == nullptr){_psins = new _InfoSingleton;}}return *_psins;}void Insert(string name, int money){_info[name] = money;}void Print(){for (auto kv : _info){cout << kv.first << " " << kv.second << endl;}}private:_InfoSingleton(){}_InfoSingleton(const _InfoSingleton& info) = delete;_InfoSingleton& operator=(const _InfoSingleton& info) = delete;map<string, int> _info;private:static _InfoSingleton* _psins;static mutex* _smtx;
};static _InfoSingleton* _psins = nullptr;
static mutex* _smtx;

1.这样写是懒汉模式,只创建一次,并且在main函数调用之后创建。

2.该代码有线程安全问题,在C++11后得到解决。

static _InfoSingleton& GetInstance()
{static _InfoSingleton sinst;return sinst;
}

注意:

1.懒汉模式需要注意线程安全问题,所以我们在类中需要有一个唯一的锁,确保判断时是串行访问的。

2.每次都先加锁再进行判断是否为空,其实是非常低效,所以我们需要双判断,第一次判断是为了抛去已经创建过的节省加锁的时间,第二次判断是为了创建对象使用的,而锁夹在中间确保第二次的判断是串行的。

3.饿汉模式不需要注意线程安全问题,因为饿汉在main调用之前就已经存在了,没有所谓的线程可以创建其他的对象。

3.单例对象释放问题

1.一般而言单例类不需要释放内存,因为单例出现的环境就是全局的,它的目的就是陪到进程执行到最后,那么其实不释放,进程结束后,操作系统也会将这一部分的资源回收。

2.特别的,如果我们需要在最后单例有一定要求,我们可以手写出析构,比如进程结束需要保存一些数据到文件中,那么我们析构可以手写要求。

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

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

相关文章

echarts制作多个纵轴的折线图

代码 <script type"text/javascript"> $(function (){var myChart echarts.init(document.getElementById(main));option {color: ["#9bbb59","#0B438B","#4141F1","#F81945","#4bacc6","#F89E19&q…

Python 电商API 开发最佳实践

一、简介 当你打卡了一家北京最具有地中海特色的餐厅&#xff0c;当我们在餐厅点餐时&#xff0c;服务员会给我们一份菜单&#xff0c;菜单上列出了所有可供选择的菜品和饮料。我们可以在菜单上选择我们想要的食物和饮料&#xff0c;然后告诉服务员我们的选择。服务员会根据我…

soft ip与hard ip

ip分soft和hard两种&#xff0c;soft就是纯代码&#xff0c;买过来要自己综合自己pr。hard ip如mem和analog与工艺有关。 mem的lib和lef是memory compiler产生的&#xff0c;基于bitcell&#xff0c;是foundry给的。 我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起…

数学建模专栏简介

&#x1f64c;作者简介&#xff1a;数学与计算机科学学院出身、在职高校高等数学专任教师&#xff0c;分享学习经验、生活、 努力成为像代码一样有逻辑的人&#xff01; &#x1f319;个人主页&#xff1a;阿芒的主页 ⭐ 高等数学专栏介绍&#xff1a;本专栏系统地梳理高等数学…

WebSocket心跳机制

WebSocket是HTML5开始提供的一种浏览器与服务器进行全双工通讯的网络技术&#xff0c;属于应用层协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。 1、创建webSocket // Create WebSocket connection. const sock…

CountDownLatch和CyclicBarrier学习

CountDownLatch和CyclicBarrier都有一个计数器 CountDownLatch countDownLatch new CountDownLatch(4); CyclicBarrier cyclicBarrier new CyclicBarrier(4) CountDownLatch 是在 countDownLatch.countDown()执行后 4-1 等到4减到0后&#xff0c;就可以继续执行程序&#x…

【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码(一)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何训…

音频降噪之人声分离

音频降噪 Ultimate Vocal Remover GUI v5.5.1工具使用 1&#xff1a;是什么 集成目前最先进的从音频文件中分离人声的源分离模型。 本工程&#xff0c;将Ultimate Vocal Remover GUI v5.5.1界面工具&#xff0c;改写成可以在服务器端批量推理的工具。 界面仓库地址&#xff…

PysparkNote006---rdd的flatMap

import pyspark.sql.functions as F from pyspark.sql import SparkSession from pyspark.sql.types import * from pyspark.sql.types import Row# 创建SparkSession对象&#xff0c;调用.builder类 # .appName("testapp")方法给应用程序一个名字&#xff1b;.getOr…

APISIX 安全评估

背景 有大佬已经对 [apisix攻击面](https://ricterz.me/posts/2021-07-05-apache-apisix-attack- surface-research.txt)做过总结。 本文记录一下自己之前的评估过程。 分析过程 评估哪些模块&#xff1f; 首先我需要知道要评估啥&#xff0c;就像搞渗透时&#xff0c;我得…

Springboot项目打包war配置详解

Springboot项目打包war配置详解 1. 排除内置tomcat依赖2. 添加servlet依赖3. 修改打包方式4. 修改主启动类5. 完整pom.xml6. 效果图 1. 排除内置tomcat依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

xmind latex【记录备忘】

xmind latex 换行 换行必须要有\begin{align}和\end{align}&#xff0c;此时再在里面用\才能换行&#xff0c;如果只写112\224是不能换行的

[Ubuntu 22.04] 安装docker,并设置镜像加速

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; doneapt install -y curl vim wget gnupg dpkg apt-transport-https lsb-release ca-certificates# 添加Docker的GPG公钥和apt源 #curl -sSL https://download.d…

pyenv教程--管理python版本

pyenv&#xff1a;简单的Python版本管理器&#xff0c;可以实现各个Python版本之间的自由切换切换。 具体讲解见如下链接。 pyenv使用讲解

RabbitMQ优先级队列的使用

RabbitMQ优先级队列的使用 生产者 public class PriorityQueue {public static void Send(){string path AppDomain.CurrentDomain.BaseDirectory;string tag path.Split(/, \\).Last(s > !string.IsNullOrEmpty(s));Console.WriteLine($"这里是 {tag} 启动了。。&…

Node2Vec spark版本采样生成序列

Node2Vec spark版本采样生成序列 前言 最近对node2vec比较感兴趣&#xff0c;再有源码的加持&#xff0c;想在生产环境复现一把&#xff0c;在复现过程中&#xff0c;发现几处bug&#xff08;有向图的生成&#xff0c;边的起点和终点的拼接符号&#xff09;&#xff0c;本文予…

理论计算初学者实用软件,PWmat Windows版本

PWmat 是一款功能强大的平面波密度泛函软件&#xff0c;拥有上千用户&#xff0c;已被广泛用于材料研发之中。但对于大多数学生来说&#xff0c;由于经费的限制&#xff0c;他们无缘于PWmat 应用。为了满足广大同学要求&#xff0c;龙讯旷腾现隆重推出免费版的PWmat Microsoft …

七、Kafka源码分析之网络通信

1、生产者网络设计 架构设计图 2、生产者消息缓存机制 1、RecordAccumulator 将消息缓存到RecordAccumulator收集器中, 最后判断是否要发送。这个加入消息收集器&#xff0c;首先得从 Deque 里找到自己的目标分区&#xff0c;如果没有就新建一个批量消息 Deque 加进入 2、消…

【Windows】不要让你的win键落灰!掌握常用的组合快捷键,使用电脑更高效了

Windows 操作系统提供了丰富的键盘快捷键&#xff0c;能够大幅提高工作效率和操作便利性。在此介绍一些与 Win 键相关的常用快捷键&#xff0c;帮助你更好地利用 Windows 系统。想要在使用电脑时更高效吗&#xff1f;掌握常用的组合快捷键&#xff0c;让你的 Win 键从此不再落灰…

【Vue】水印组件

前言&#xff1a; 最近在工作中接收到了一个给页面添加水印的需求&#xff0c;在网上看到了各种各样的写法&#xff0c;但是感觉写的都比较啰嗦或者复杂&#xff0c;就想着自己写个组件&#xff0c;可以在以后得工作中经常用到&#xff0c;目前是使用Vue技术写的&#xff0c;如…