c++关键字: =delete和=default
=delete
概述
=delete关键字是c++11新增的关键字,主要用于的场景是:当我们不希望类中的函数被类对象在外部调用的时候,我们就可以使用这个关键字。
其实,之前我们实现这种功能是将这些函数放在private修饰符下,但是这种方法是依靠语法特性来实现的,有些地方可能并不合适。
举个例子: 使用private虽然在类外不能使用这些函数了,但是在类的内部还是可以使用的,但是我们目前的要求是在任何地方都不能使用这些函数,那么这时候就得使用=delete关键字了。(因为用来它之后就相当于删除了,自然哪里也用不了了)
疑问: 那我们不用直接将这些函数删除不就好了,为什么多次一举呢?对于普通的函数,我们直接删除了自然时最好的,也可以减少歧义。
但是对于类的构造函数呢? 即使我们删除了,编译器也会自己给我们创建一个,这样即使我们删除掉,最起码在类内部还时可以使用的,所以这时候我们就得使用=delete关键字了。
使用=delete修饰类的构造函数之后,编译器就不会自动提供了,而且编译器依然会认为它们被删除了无法使用。
1. 此关键字用于构造函数
对于构造函数,无论隐式的(就是编译器自己提供的)还是显示的(我们自己写的),在创建实例对象的时候,编译器都会默认去调用这些函数。但是有些时候,我们并不希望外界使用我们这些函数,那么就可以使用=delete关键字修饰,这样就相当于删除了对应的构造函数。
代码例子:
c++中有四种构造函数: 默认构造,有参构造,拷贝构造,赋值构造(=运算符重载)
#include <iostream>
#include <stdlib.h>using namespace std;class A {
public:A() = delete;A(const A& a) = delete;A(int a) = delete;A& operator=(const A& a) = delete;
};int main(void) {A a; // 错误: 无法引用 "A" 的默认构造函数 -- 它是已删除的函数system("pause");return 0;
}
上面的代码,我们对类A中的所以构造函数都使用了=delete关键字。我们在main函数中创建对象a,会报错,因为创建对象会调用默认构造函数,但是我们使用=delete关键字修饰了默认构造函数,就相当于它被删除了,会报错。(其它的构造函数也一样,可以自己尝试)
一般情况下,我们是不会将所有的构造函数都用=delete(除非你这个类不常见对象),否则,建议只是根据需要将对应的构造函数=delete即可。比如,将拷贝构造函数和复制构造函数用哪个delete修饰,不允许对类对象进行拷贝了,但是可以使用默认构造函数创建对象。(当然根据具体需要来选择)
2. 此关键字用于普通成员函数
其实用于普通成员函数,也是一样的道理,编译器会认为这个函数删除了,但是成员函数和构造函数不一样,我们为什么不直接将其删除了,反正也不用了,何必多此一举。
当然,有一种情况下也是可以使用的 -- 避免传参时进行形式转换。
一般情况,参数传递的时候,编译器都会进行隐式转换比如:
#include <iostream>
#include <stdlib.h>using namespace std;class A {
public:void func(int a) {printf("%d\n", a);}
};int main(void) {A a; a.func(1.2); // 打印结果为1system("pause");return 0;
}
上面,我们给函数func传入一个double的值1.2,但是func的参数类型为int型,所以传入之后进行了隐式转换,将double的1.2转化为了int的1。
下面代码就可以避免这种隐式转换
#include <iostream>
#include <stdlib.h>using namespace std;class A {
public:void func(int a) {printf("%d\n", a);}void func(double a) = delete;
};int main(void) {A a; a.func(1.2); // 出错system("pause");return 0;
}
其实我们使用函数重载就可以避免,也就是我们在传入double的值调用的是形参为double的函数,这样就避免了。
但是,如果我们不希望外界使用形参为double的函数,还要避免隐式转换,就可以使用上面这种方式,我们直接传入double的值,就不会隐式转换而是直接报错了。
3. 一般情况下,此关键字不要修饰析构函数
因为如果使用=delete修饰析构函数,那么我们创建的对象就无法释放了。会一直占用空间。因为释放对象,是需要调用析构函数的。
=default
概述
default就是默认的意思,这个关键字用来修饰构造函数,告诉编译器给函数实现默认的实现。
其实就是给指定函数实现对应默认的代码,适当的使用可以提高代码效率和可读性。只能用于默认构造,拷贝构造,赋值构造和析构, -- 因为这些函数我们不写,编译器也会替我们写(编译器知道默认怎么写),=default关键字就是让编译器替我们写函数的实现,前提是编译器知道怎么写才行。(也就是默认构造,拷贝构造,赋值构造和析构才行)
当然,如果函数中需要实现我们想要的功能(比如,开辟空间,释放空间等),或者说有函数实现,就不能使用=default来修饰。
如果在类内部给对应函数添加=default,那么其实现的函数是内联的,如果不希望是内联的那就在类外部进行指定=default。
代码例子:
class A {
public:A() = default;A(const A& a) = default;A& operator=(const A& a) = default;~A() = default;
};
相关文章:
c++关键字: =delete和=default
delete 概述 delete关键字是c11新增的关键字,主要用于的场景是:当我们不希望类中的函数被类对象在外部调用的时候,我们就可以使用这个关键字。 其实,之前我们实现这种功能是将这些函数放在private修饰符下,但是这种方…...
JSON
文章目录 JSONJSON 的定义格式快速入门JSON 对象和字符串对象转换JSON 在 java 中使用JSON与java对象的转换JSON与List集合的转换JSON与Map的转换 JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式…...

Python | 超前滞后分析
Nino SST Indices (Nino 12, 3, 3.4, 4; ONI and TNI) 有几个指标用于监测热带太平洋,所有这些指标都是基于海表温度(SST)异常在一个给定的区域的平均值。通常,异常是相对于30年的周期来计算的。厄尔尼诺3.4指数(Nio 3.4 index)和海洋厄尔尼诺指数(Ocea…...

Linux CPU利用率
Linux CPU利用率 在线上服务器观察线上服务运行状态的时候,绝大多数人都是喜欢先用 top 命令看看当前系统的整体 cpu 利用率。例如,随手拿来的一台机器,top 命令显示的利用率信息如下 这个输出结果说简单也简单,说复杂也不是那么…...
vue3实现导出pdf、png功能
准备做的系统中出现了 想导出当前页面的png或者pdf设计数据较多后端做可能比较麻烦 就自己研究了一下 1、安装html2canvas 、jspdf包 npm install --save html2canvas // 可以将dom元素转为一张图片 npm install --save jspdf // 导出为PDF格式 2、vue组件中引用&#x…...

what is tty?
waht is tty? 黑话:TTY 为什么使用Linux的时候CtrlC就会终止一个命令运行,ta是如何设置的? stty -a 桌面切换 CTRL ALT F1 – 锁屏 CTRL ALT F2 – 桌面环境 CTRL ALT F3 – TTY3 CTRL ALT F4 – TTY4 CTRL ALT F5 – TTY5 CTRL ALT F6 – TTY6...

在vite中限制node版本
1.修改package.json文件 {"name": "wine-store-frontend","version": "0.0.0","private": true,"type": "module","scripts": {"dev": "vite --open","build"…...

07 Php学习:运算符
PHP 算术运算符 在 PHP 中,算术运算符用于执行基本的数学运算,包括加法、减法、乘法、除法、取余数,负数运算、取反和并置运算。以下是这些运算符的详细解释和示例: 加法运算符 :用于将两个数值相加。 $a 5; $b 3;…...

做了多年前端,有没有想在python,go,nodejs,.net,java,c++中学一门后端,推荐
作为一名经验丰富的前端开发者,选择学习后端技术是一个重要的职业发展决策。Python、Go、Node.js、.NET、Java和C都是强大的后端开发语言,每门语言都有其特定的优势和应用场景。以下是对这些技术的分析,以帮助你做出选择: 目录 …...

JR-SMD201-P便携式网络解码器
详细介绍: JR-SMD201-P便携式网络解码器采用1/2U设计,支持AVS/H.265/H.264/MPEG2解码,支持IP输入,支持1080P/1080I/720P/576I/480I多种分辨率,支持DRA/AC3/EAC3/AAC/MPEG等音频。 产品特点 支持输入方式IP 接口丰富&a…...
线程池阻塞队列的选择
一、背景 想起前两年被问到阻塞队列怎么选,有界是必然的, ArrayBlockingQueue、LinkedBlockingQueue怎么选呢。 二、打开源码看看 ArrayBlockingQueue arrayBlockingQueue new ArrayBlockingQueue(3);LinkedBlockingQueue linkedBlockingQueue new Lin…...

linux内核驱动-在内核代码里添加设备结点
linux中,一切皆文件 我们在用户层用一些系统函数(如:fopen等等)时,会进入内核,内核会在字符注册了的设备号链表中查找。如果找到就运行我们写的设备文件的(驱动)函数 我们在前面已经…...
【算法优选】 动态规划之简单多状态dp问题——贰
文章目录 🎋前言🌴[买卖股票的最佳时机含冷冻期](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/)🚩题目描述🚩算法思路:🎈状态表示:🎈…...

【算法刷题 | 二叉树 06】4.10( 路径总和、路径总和 || )
文章目录 13.路径总和13.1问题13.2解法一:递归13.2.1递归思路(1)确定递归函数参数以及返回值(2)确定终止条件(3)确定递归逻辑 13.2.2代码实现 14.路径总和 ||14.1问题14.2解法一:递归…...

代码学习记录37----动态规划
随想录日记part37 t i m e : time: time: 2024.04.06 主要内容:今天开始要学习动态规划的相关知识了,今天的内容主要涉及四个方面: 完全背包;零钱兑换 II ;组合总和 Ⅳ 和单词拆分 …...

Spring Boot:Web开发之三大组件的整合
Spring Boot 前言Spring Boot 整合 ServletSpring Boot 整合 FilterSpring Boot 整合 Listener前言 在 Web 开发中,Servlet 、Filter 和 Listener 是 Java Web 应用中的三大组件。Servlet 是 Java 代码,通过 Java 的 API 动态的向客户端输出内容。Filter 是处于客户端与服务…...
2024.3.15力扣每日一题——卖木头块
2024.3.15 题目来源我的题解方法一 记忆化搜索(自顶向下)方法二 动态规划(自底向上) 题目来源 力扣每日一题;题序:2312 我的题解 方法一 记忆化搜索(自顶向下) 用 f(x,y)表示当木…...

vue快速入门(七)内联语句
注释很详细,直接上代码 上一篇 新增内容 button点击事件绑定内联语句写法与要求 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wid…...

Docker实战教程 第2章 Docker基础
3-1 Docker介绍 什么是Docker 虚拟化,容器 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上&…...
【S32K3 MCAL配置】-3.2-CANFD配置-发送“经典CAN/CANFD标准帧“和“经典CAN/CANFD扩展帧“(基于MCAL+FreeRTOS)
"><--返回「Autosar_MCAL高阶配置」专栏主页--> 目录 实现的架构:基于MCAL层 前期准备工作: 1 评估板S32K312EVB-Q172中CAN外设...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...