当前位置: 首页 > news >正文

C++特殊类设计(不能被拷贝的类、只能在堆上创建对象的类、不能被继承的类、单例模式)

C++特殊类设计

在实际应用中,可能需要设计一些特殊的类对象,如不能被拷贝的类、只能在堆上创建对象的类、只能在栈上创建对象的类、不能被继承的类、只能创建一个对象的类(单例模式)

1. 不能被拷贝的类

拷贝只会发生在两个场景中:拷贝构造函数和赋值运算符重载。因此,让一个类禁止被拷贝,只需要让其拷贝构造函数和赋值运算符重载不能被调用即可

1.1 c++98做法

c++98通过将拷贝构造函数和赋值运算符重载只声明不定义,并将其访问权限设置为私有实现禁止被拷贝。

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

1.2 现代做法

使用c++11提供的delete关键字“删除”拷贝构造函数和赋值运算符重载。

class CopyBan
{
private:CopyBan(const CopyBan& cb) = delete;CopyBan& operator=(const CopyBan& cb) = delete;
};

2. 只能在堆上创建对象的类

2.1 直接法

要使一个类只能在堆上创建对象,思路是:

  1. 将类的构造函数和拷贝构造函数私有,防止别人调用拷贝在栈上生成对象。
  2. 再提供一个静态成员函数,在该静态成员函数内部完成堆对象的创建。
class HeapOnly
{static HeapOnly* Create()//静态解决“先有函数还是现有对象问题”{return new HeapOnly;}
private:HeapOnly(){}
};

但此不能完全封死在栈上创建对象,如果通过 Create()函数先创建一个堆上的对象,再使用默认拷贝构造拷贝堆上的对象,就能够实现在栈上创建对象。

HeapOnly* ho1 = HeapOnly::Create();
HeapOnly* ho2(ho1);

所以最后还需要封死通过拷贝构造创建栈上对象:

c++98:private:HeapOnly& HeapOnly(const HeapOnly& ho){}

c++11:HeapOnly& HeapOnly(const HeapOnly& ho)=delete;

2.2 私有析构函数法

设计不能被拷贝的类还有一种方法,通过私有化析构函数,让栈上对象无法在离开作用域时自动调用析构函数,因此在栈上的创建对象的代码都不能被编译通过。再设计一个 release()函数手动释放堆上的对象

class HeapOnly
{
public:static HeapOnly* Create(){return new HeapOnly;}void relase(){delete this;}
private:~HeapOnly(){}
};

3. 只能在栈上创建对象的类

要使一个类只能在栈上创建对象,思路是:

  1. 私有化构造函数
  2. 设计静态函数返回对象
class StackOnly
{
public:static StackOnly Create(){return StackOnly();}void* operator new(size_t size) = delete;void operator delete(void* p) = delete;private:StackOnly():_a(0){}int _a;
};

设计只能在栈上创建对象的类还要注意将new和delete删除,避免使用new通过拷贝构造创建堆上对象。且由于 Create()函数被设计成传值返回,不能直接通过删除拷贝构造实现(因为临时对象)。

删除new和delete的原理是,编译器默认生成一个new和一个delete,现将重载new和delete在类中重载,那么类对象会调用重载的new和重载的delete(重载后不再默认生成),但由于重载的new和重载的delete被删除,类对象在创建时便无法使用。

StackOnly so1 = StackOnly::Create();
StackOnly* so2 = new StackOnly(so1);

4. 不能被继承的类

要使一个类不能被继承,方法是:

  1. c++98:基类析构函数私有,派生类不能调用基类的构造函数,无法编译通过
  2. c++11:使用final关键字标记基类,表示该类不能被继承

5. 单例模式

单例模式要求一个类只能创建一个对象,该模式可以抱枕系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

单例模式有两种实现模式:

  1. 饿汉模式

  2. 懒汉模式

5.1 饿汉模式

饿汉形容程序对对象的需要比较紧迫,不管将来用不用,在程序启动时就马上先创建一个唯一的实例对象(一般在main函数之前创建)。

#include<iostream>
using namespace std;class ehan
{
public:static ehan* GetInstance(){return &_e;}int SetInfo(int info){_info = info;return _info;}ehan(const ehan& e) = delete;ehan& operator=(const ehan& e) = delete;
private:ehan(){}int _info;static ehan _e;//声明
};ehan ehan::_e;//定义
int main()
{cout<<ehan::GetInstance()->SetInfo(1);return 0;
}

优先:简单

缺点:可能会导致进程启动慢,且如果有多个单例类使用饿汉模式,它们的对象实例启动顺序不确定

5.2 懒汉模式

懒汉模式可以完美解决饿汉模式的缺点,懒汉模式一般在第一次调用 GetInstance() 的时候创建单例对象。

#include<iostream>
using namespace std;class lanhan
{
public:static lanhan* GetInstance(){static lanhan _lh;return &_lh;}int SetInfo(int info){_info = info;return _info;}lanhan(const lanhan& e) = delete;lanhan& operator=(const lanhan& e) = delete;
private:lanhan(){}int _info;
};int main()
{cout<<lanhan::GetInstance()->SetInfo(1);return 0;
}

这里在 GetInstance()里 定义了一个局部静态对象 static lanhan _lh; ,即使调用多次 GetInstance(),这个创建对象的代码也只会执行一次,但这种使用方法是c++11之后支持,且有线程安全风险

传统且线程安全方法:

#include<iostream>
#include<mutex>
using namespace std;class lanhan
{
public:static lanhan* GetInstance(){if (_lh == nullptr)//双重检查保证线程安全{unique_lock<mutex> lock(_mtx);if (_lh == nullptr){_lh = new lanhan;}}return _lh;}int SetInfo(int info){_info = info;return _info;}lanhan(const lanhan& e) = delete;lanhan& operator=(const lanhan& e) = delete;
private:lanhan(){}int _info;static mutex _mtx;static lanhan* _lh;};
lanhan* lanhan::_lh = nullptr;
mutex lanhan::_mtx;int main()
{cout<<lanhan::GetInstance()->SetInfo(1);return 0;
}

相关文章:

C++特殊类设计(不能被拷贝的类、只能在堆上创建对象的类、不能被继承的类、单例模式)

C特殊类设计 在实际应用中&#xff0c;可能需要设计一些特殊的类对象&#xff0c;如不能被拷贝的类、只能在堆上创建对象的类、只能在栈上创建对象的类、不能被继承的类、只能创建一个对象的类&#xff08;单例模式&#xff09;。 1. 不能被拷贝的类 拷贝只会发生在两个场景…...

【小白学机器学习34】用python进行基础的数据统计 mean,var,std,median,mode ,四分位数等

目录 1 用 numpy 快速求数组的各种统计量&#xff1a;mean, var, std 1.1 数据准备 1.2 直接用np的公式求解 1.3 注意问题 1.4 用print() 输出内容&#xff0c;显示效果 2 为了验证公式的后背&#xff0c;下面是详细的展开公式的求法 2.1 均值mean的详细 2.2 方差var的…...

安装 Docker(使用国内源)

一、安装Docker-ce 1、下载阿里云的repo源 [rootlocalhost ~]# yum install yum-utils -y && yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo && yum makecache # 尝试列出 docker-ce 的版本 [rootlocalh…...

Ajax学习笔记,第一节:语法基础

Ajax学习笔记&#xff0c;第一节&#xff1a;语法基础 一、概念 1、什么是Ajax 使用浏览器的 XMLHttpRequest 对象 与服务器通信2、什么是axios Axios是一个基于Promise的JavaScript库&#xff0c;支持在浏览器和Node.js环境中使用。相较于Ajax&#xff0c;Axios提供了更多…...

《用Python画蔡徐坤:艺术与编程的结合》

简介 大家好&#xff01;今天带来一篇有趣的Python编程项目&#xff0c;用代码画出知名偶像蔡徐坤的形象。这个项目使用了Python的turtle库&#xff0c;通过简单的几何图形和精心设计的代码来展示艺术与编程的结合。 以下是完整的代码和效果介绍&#xff0c;快来试试看吧&…...

Unity中动态生成贴图并保存成png图片实现

实现原理&#xff1a; 要生成长x宽y的贴图&#xff0c;就是生成x*y个像素填充到贴图中&#xff0c;如下图&#xff1a; 如果要改变局部颜色&#xff0c;就是从x1到x2(x1<x2),y1到y2(y1<y2)这个范围做处理&#xff0c; 或者要想做圆形就是计算距某个点&#xff08;x1,y1&…...

Mac配置maven环境及在IDEA中配置Maven

Mac配置maven环境及在IDEA中配置Maven 1. 介绍 Maven是一款广泛用于Java等JVM语言项目的工具&#xff0c;它以项目对象模型&#xff08;POM&#xff09;为基础进行项目管理&#xff0c;通过POM文件来定义项目信息和依赖关系。同时&#xff0c;它也是构建自动化工具&#xff0…...

Reactor 模式的理论与实践

1. 引言 1.1 什么是 Reactor 模式&#xff1f; Reactor 模式是一种用于处理高性能 I/O 的设计模式&#xff0c;专注于通过非阻塞 I/O 和事件驱动机制实现高并发性能。它的核心思想是将 I/O 操作的事件分离出来&#xff0c;通过事件分发器&#xff08;Reactor&#xff09;将事…...

vim 一次注释多行 的几种方法

在 Vim 中一次注释多行是一个常见操作。可以使用以下方法根据你的具体需求选择合适的方式&#xff1a; 方法 1&#xff1a;手动插入注释符 进入正常模式&#xff1a; 按 Esc 确保进入正常模式。 选择需要注释的多行&#xff1a; 移动到第一行&#xff0c;按下 Ctrlv 进入可视块…...

问题记录-Java后端

问题记录 目录 问题记录1.多数据源使用事务注意事项&#xff1f;2.mybatis执行MySQL的存储过程&#xff1f;3.springBoot加载不到nacos配置中心的配置问题4.服务器产生大量close_wait情况 1.多数据源使用事务注意事项&#xff1f; 问题&#xff1a;在springBoot项目中多表处理数…...

李春葆《数据结构》-课后习题代码题

一&#xff1a;假设不带权有向图采用邻接矩阵 g 存储&#xff0c;设计实现以下功能的算法&#xff1a; &#xff08;1&#xff09;求出图中每个顶点的入度。 代码&#xff1a; void indegree(MatGraph g){int i,j,n;printf("各个顶点的入度&#xff1a;\n");for(i…...

51c~C语言~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/12652943 一、嵌入式开发中的C语言编译器 如果你和一个优秀的程序员共事&#xff0c;你会发现他对他使用的工具非常熟悉&#xff0c;就像一个画家了解他的画具一样。----比尔.盖茨1 不能简单的认为是个工具 嵌入式程序开发…...

【Python】构建事件驱动架构:用Python实现实时应用的高效系统

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 事件驱动架构(Event-Driven Architecture,EDA)是一种基于事件流动进行系统设计的模式,广泛应用于游戏开发、实时监控和分布式系统中。它通过解耦事件的生产者和消费者,提升系统的可扩展性和灵活性。本文章从…...

Git(一)基本使用

目录 一、使用git -v 查看安装git版本 二、使用mkdir 创建一个文件&#xff0c;并使用 git init 在该目录下创建一个本地仓库&#xff0c; 三、通过git clone命令接入线上仓库 四、使用git status查看仓库状态信息 五、利用echo写入一个文件 并使用cat进行查看 【Linux】e…...

HarmonyOS应用开发者基础认证,Next版本发布后最新题库(10月8日更新题库未收录)

笔者会尽量找到答案的出处&#xff0c;力求答案准确无误。有些题目答案可能有错&#xff0c;也有一些笔者实在找不到出处&#xff0c;也不知道答案的&#xff0c;如果读者发现错误或有补充建议&#xff0c;欢迎评论或私信笔者。您的每一条反馈都是宝贵的&#xff0c;能够帮助笔…...

【PGCCC】Postgresql BRIN 索引原理

前言 postgresql 提供了块级索引&#xff08;简称 BRIN&#xff09;&#xff0c;主要适用于类似时序数据之类的&#xff0c;有着天然的顺序&#xff0c;而且都是添加写的场景。相比于 btree 索引&#xff0c;它的体积小得多&#xff0c;非常适用于大数据量的场景。 原理 pos…...

腾讯云 AI 代码助手:产品研发过程的思考和方法论

一、文章摘要 本文将详细阐述 腾讯云 AI 代码助手的历史发展形态与产品整体架构&#xff0c;并从技术、研发方法论的角度分别阐述了产品的研发过程。 全文阅读约 5&#xff5e;8 分钟。 二、产品布局 AI 代码助手产品经历了三个时代的发展 第一代诸如 Eclipse、Jetbrains、V…...

Matlab 深度学习 PINN测试与学习

PINN 与传统神经网络的区别 与传统神经网络的不同之处在于&#xff0c;PINN 能够以微分方程形式纳入有关问题的先验专业知识。这些附加信息使 PINN 能够在给定的测量数据之外作出更准确的预测。此外&#xff0c;额外的物理知识还能在存在含噪测量数据的情况下对预测解进行正则…...

【Angular】async详解

在 Angular 中&#xff0c;async 关键字用于定义异步函数&#xff0c;通常与 await 一起使用来处理 Promise。这使得异步代码看起来更像同步代码&#xff0c;从而更容易理解和维护。 基本用法 定义异步函数&#xff1a;使用 async 关键字。等待 Promise 解析&#xff1a;使用…...

抖音SEO矩阵系统:开发技术分享

市场环境剖析 短视频SEO矩阵系统是一种策略&#xff0c;旨在通过不同平台上的多个账号建立联系&#xff0c;整合同一品牌下的各平台粉丝流量。该系统通过遵循每个平台的规则和内容要求&#xff0c;输出企业和品牌形象&#xff0c;以矩阵形式增强粉丝基础并提升商业价值。抖音作…...

Axure Mac全汉化3步法:设计师效率提升实战指南

Axure Mac全汉化3步法&#xff1a;设计师效率提升实战指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包&#xff0c;不定期更新。支持 Axure 9、Axure 10。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 你是否曾…...

X-TRACK二次开发终极指南:如何基于开源框架快速扩展新功能

X-TRACK二次开发终极指南&#xff1a;如何基于开源框架快速扩展新功能 【免费下载链接】X-TRACK A GPS bicycle speedometer that supports offline maps and track recording 项目地址: https://gitcode.com/gh_mirrors/xt/X-TRACK X-TRACK是一款支持离线地图和轨迹记…...

打破3D创作壁垒:零成本解决方案实现Blender到Unreal Engine的无缝资产迁移

打破3D创作壁垒&#xff1a;零成本解决方案实现Blender到Unreal Engine的无缝资产迁移 【免费下载链接】bl_datasmith Blender addon to export UE4 Datasmith format 项目地址: https://gitcode.com/gh_mirrors/bl/bl_datasmith 你是否也曾因格式转换丢失过数小时的工作…...

OpenClaw+GLM-4.7-Flash:个人博客内容自动生成与发布

OpenClawGLM-4.7-Flash&#xff1a;个人博客内容自动生成与发布 1. 为什么选择这个技术组合 去年夏天&#xff0c;我发现自己陷入了写作瓶颈——每周要产出3篇技术博客&#xff0c;但80%的时间都消耗在资料收集和格式调整上。直到发现OpenClawGLM-4.7-Flash这个组合&#xff…...

微信聊天记录备份全攻略:从环境搭建到数据安全实战指南

微信聊天记录备份全攻略&#xff1a;从环境搭建到数据安全实战指南 【免费下载链接】WechatBakTool 基于C#的微信PC版聊天记录备份工具&#xff0c;提供图形界面&#xff0c;解密微信数据库并导出聊天记录。 项目地址: https://gitcode.com/gh_mirrors/we/WechatBakTool …...

Boss-Key:职场隐私保护与效率提升的开源解决方案

Boss-Key&#xff1a;职场隐私保护与效率提升的开源解决方案 【免费下载链接】Boss-Key 老板来了&#xff1f;快用Boss-Key老板键一键隐藏静音当前窗口&#xff01;上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在数字化办公环境中&#xff…...

STM32 RTC硬件自检工具CheckRTC:轻量级实时时钟可信度验证

1. 项目概述CheckRTC 是一个面向 STM32 系列微控制器的轻量级 RTC&#xff08;实时时钟&#xff09;模块自检与功能验证程序。其核心目标并非提供通用 RTC 驱动&#xff0c;而是作为嵌入式底层开发中关键的硬件可信度验证工具——在系统启动早期、固件升级后、或长期运行出现时…...

从零搭建企业级开源大模型平台:Ollama+Llama3+open-webui实战指南

1. 为什么选择OllamaLlama3open-webui组合&#xff1f; 最近两年大语言模型的发展速度简直让人瞠目结舌&#xff0c;从最初的GPT-3到现在的Llama3&#xff0c;模型能力突飞猛进的同时&#xff0c;部署门槛也在不断降低。作为一个在AI领域摸爬滚打多年的老手&#xff0c;我实测过…...

跨语言沟通的革命性突破:FunASR语音翻译系统全解析

跨语言沟通的革命性突破&#xff1a;FunASR语音翻译系统全解析 你是否还在为国际会议中的语言障碍而烦恼&#xff1f;是否因跨国团队协作中的沟通不畅而效率低下&#xff1f;FunASR语音翻译系统将彻底改变这一现状&#xff0c;让跨语言交流如母语般自然流畅。读完本文&#xf…...

MinerU本地部署安全吗?数据隐私保护实战配置

MinerU本地部署安全吗&#xff1f;数据隐私保护实战配置 1. 引言&#xff1a;当AI遇见你的敏感文档 想象一下这个场景&#xff1a;你有一份包含商业机密的合同PDF&#xff0c;或者一份涉及个人隐私的医疗报告扫描件。你想用AI快速提取里面的关键信息&#xff0c;但又担心把文…...