【C++】C++11之新的类功能与可变参数模板

目录

一、新的默认成员函数

二、新的关键字

2.1 default

2.2 detele

2.3 final和override

三、可变参数模板

3.1 定义

3.2 递归展开参数包

3.3 逗号表达式展开参数包

3.4 emplace_back

一、新的默认成员函数

在C++11之前,默认成员函数只有六个,而C++11新增了两个默认成员函数,即移动构造函数和移动赋值运算符重载函数

在前面对右值引用的学习中我们已经见过了这两个函数,关于它们的一些特性还有需要注意的地方

  • 如果用户没有显式实现一个移动构造函数,且没有显式实现析构函数、拷贝构造、赋值重载中的任意一个,那么编译器才会自动生成一个默认的移动构造函数
  • 移动赋值重载函数与移动构造同理,只要四个函数都没有被实现,编译器才会生成默认的
  • 移动构造函数会对内置类型成员进行逐字节的浅拷贝,对于自定义类型成员会调用该成员自己的移动构造,如果没有实现移动构造则调用其拷贝构造
  • 移动赋值重载函数与移动构造同理,对内置类型成员进行浅拷贝,对于自定义类型成员会调用该成员自己的移动赋值,如果没有实现移动赋值则调用其拷贝赋值
  • 如果用户已经实现了移动构造和移动赋值,编译器不会生成拷贝构造拷贝赋值

关于右值引用,如果还有不了解的可以移步

【C++】C++11之右值引用-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Eristic0618/article/details/140826229?spm=1001.2014.3001.5502


二、新的关键字

2.1 default

前面提到,如果四个默认成员函数被实现了其中一个,编译器就不会生成默认的移动构造函数

但是假如我们就想让编译器给我们生成某个默认的成员函数呢?

在C++11中新增了default关键字,用来显式的指定让某个默认成员函数被生成

例如:

class A
{
public:A(int x) //构造:_a(x){}A(const A& a) //拷贝构造:_a(a._a){}A(A&& a) = default; //强制生成默认移动构造private:int _a;
};

2.2 detele

与用于释放动态分配的内存空间的delete运算符进行区分,C++11新增的delete关键字与default的功能相反,其功能是可以禁止生成指定的函数。这个功能看似很鸡肋,其实大有妙用

如果我们想让一个类无法被实例化,该如何实现呢?以前我们需要将构造函数定义为私有成员,现在则只需要直接将这个类的构造函数用delete修饰即可,例如:

还有更巧妙的用法,我们知道如果一个函数的参数类型为int,我们还是可以把double类型的参数传入,因为会发生隐式类型转换

但是如果我们不想这样的事情发生,只希望传入的参数就是我们想要的类型,该如何实现呢?

我们只需要再声明一个完全一样的函数,把参数改为double,然后再用delete修饰即可,例如:

2.3 final和override

这两个关键字在我以前的文章中有提到,有兴趣的可以移步【C++】多态-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Eristic0618/article/details/137755151?spm=1001.2014.3001.5502


三、可变参数模板

可变参数列表,即长度不定的参数列表,在过去我们实际上已经接触过可变参数列表了,例如C语言的scanf和printf,其函数参数的数量是不定的

但是在过去,模板参数的数量一直是固定的,直到C++11出现了可变参数模板,模板才能支持可变参数列表。可变参数模板能够支持传入任意个数、任意类型的参数

3.1 定义

首先来看看如何声明一个支持可变参数模板的函数模板:

template <class... Args>
void Print(Args... a)
{}

在class或typename后加上省略号即可声明一个模板参数包。

在函数的参数列表中,通过在模板参数包后加上省略号即可声明一个函数形参参数包,其中包含任意数量的模板参数

但是我们无法通过类似下标等方式来获取其中的参数,只能通过特定方式将参数包展开来获取参数

3.2 递归展开参数包

我们知道,在调用一个函数的时候,我们传入的参数和函数的参数列表是要一一对应的。

利用这个性质,我们让函数的第一个参数是单独的参数,让第二个参数是一个参数包,这样,我们就可以每次将参数包内的第一个参数提取出来,剩余的参数进入第二个参数成为新的参数包

例如:

template<class T>
void Print(const T& val)
{cout << val << endl;
}template<class T, class... Args>
void Print(T val, Args... a)
{cout << val << " ";Print(a...);
}int main()
{Print(1, 2, 3, 4);return 0;
}

像这样,当我们在主函数中传入4个参数,就会调用上面的第二个Print

数字1则进入函数的第一个参数,2、3、4进入第二个参数变为参数包

函数内部将1打印出来,剩余参数继续递归调用自己

等到最后只剩一个参数了,则会调用上面的只有一个参数的Print,结束递归

这种通过递归展开参数包的方式,就需要一个递归终止函数,也就是上面的第一个Print

除此之外,还有一种展开参数包的方式

3.3 逗号表达式展开参数包

这种方式则更为抽象一点,先来看看是如何用逗号表达式来展开一个参数包的

template<class T>
void Print(T& val)
{cout << val << " ";
}template<class... Args>
void Get(Args... a)
{int arr[] = { (Print(a), 0)... };cout << endl;for (auto i : arr) //打印看看数组内的值{cout << i << " ";}
}int main()
{Get(1, 2, 3, 4);return 0;
}

首先,逗号表达式会从头到尾执行所有的表达式,其结果是最后一个表达式的值,所以 (Print(a), 0) 会执行一次Print函数并返回0。除此之外还用到了C++11的另一个特性即初始化列表,通过初始化列表来初始化一个变长数组,整个初始化列表{ (Print(a), 0)... }将会展开成sizeof(参数包)个逗号表达式,通过这种方式就可以在构造数组时展开参数包

如果你对上面的过程有疑惑,我们可以将逗号表达式中的Print函数和0换个位置,看看数组的内容会不会改变,前提是Print函数得返回一个值

可以看到,此时逗号表达式的结果就变为了Print函数的返回值,数组的内容也变为了1、2、3、4

3.4 emplace_back

C++11中一些容器多了名为emplace_back的接口,用于在尾部进行元素插入

有人会说,尾插直接用push_back不就好了?emplace_back的优势在哪呢?

首先我们可以看到emplace_back支持了可变参数模板和万能引用,而push_back的参数数量是固定的,这就导致如果容器元素的类型是pair的话,就必须提前用make_pair等构造好再传参

例如:

int main()
{list<pair<int, int>> lt2;lt2.push_back(make_pair(1, 1));return 0;
}

如果换成emplace_back的话,我们就不需要提前构造,直接把参数传入即可,因为emplace_back使用了可变参数列表,不需像push_back一样一次只能传一个参数

完. 

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

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

相关文章

【机器学习算法基础】(基础机器学习课程)-11-k-means-笔记

示例案例 为了更好地理解 K-Means 算法&#xff0c;下面通过一个简单的案例进行说明。 假设我们有以下 10 个二维数据点&#xff0c;表示不同商店的销售额&#xff08;单位&#xff1a;千元&#xff09;和顾客数&#xff08;单位&#xff1a;人&#xff09;&#xff1a; [(1…

常见cms漏洞之dedecms

DedeCMS是织梦团队开发PHP 网站管理系统&#xff0c;它以简单、易用、高效为特色&#xff0c;组建出各种各样各具特色的网站&#xff0c;如地方门户、行业门户、政府及企事业站点等。 下载地址请网上自行寻找 搭建方式选择php study 首先搭建环境 #前台http://localhost/dedecm…

Java AI伪原创视频创作视频提取文案改写去水印系统小程序源码

&#x1f525;AI赋能创作新纪元&#xff01;伪原创视频文案提取改写去水印全能系统大揭秘 &#x1f680; 开篇&#xff1a;创意无界&#xff0c;AI来助力 在这个视觉盛行的时代&#xff0c;视频创作成为了表达自我、传递信息的重要方式。但你是否曾为寻找灵感、撰写文案、处理…

sa-token登录机制以及网关统一鉴权环境搭建

文章目录 1.sa-token1.37集成&#xff08;基于token&#xff09;1.文档网址2.**sun-club-auth-application-controller引入依赖**3.application.yml4.sun-club-auth-application-controller测试的controller1.UserController.java2.启动测试1.登录&#xff0c;得到satoken2.验证…

【FPGA】cordic算法实现三角函数

参考资料&#xff1a;https://zhuanlan.zhihu.com/p/638520243https://zhuanlan.zhihu.com/p/638520243

Hadoop学习(三)

一、MapReduce框架原理 1.1InputFormat数据输入 MapTask并行度决定机制 1&#xff09;数据块&#xff08;HDFS存储数据单位&#xff09;&#xff0c;物理上把数据分成一块一块 2&#xff09;数据切片&#xff08;MapReduce程序计算输入数据的单位)&#xff1a;只是在逻辑上…

Lanproxy开箱即用的内网穿透工服务!!

Lanproxy快速上手配置服务器转发到内网!! 本教程云服务器推荐使用的开发环境如下&#xff1a;服务器端配置配置端口登录Web界面 内网客户端配置下载客户端配置客户端端口 最终效果测试 本文主要记录了使用Lanproxy搭建内网穿透服务的过程&#xff0c;其中包括服务端和客户端的详…

CSP2019第二题: 公交换乘

CSP 2019 公交换乘 题目来源&#xff1a;牛客网 题目&#xff1a;* 示例1 输入 6 0 10 3 1 5 46 0 12 50 1 3 96 0 5 110 1 6 135输出 36题意&#xff1a; 根据输入&#xff0c;计算地铁花费不能用到优惠券的公交车的花费 知识点&#xff1a; 结构体 思路&#xff1…

谷粒商城实战笔记-vagrant避坑指南

文章目录 一&#xff0c;虚拟机磁盘空间不足问题原因解决方案 二&#xff0c;虚拟机导致C盘空间不足 一&#xff0c;虚拟机磁盘空间不足 使用vagrant管理虚拟机的过程中遇到了一个问题&#xff0c;虚拟机安装完成后&#xff0c;很快磁盘dev/sda1就满了&#xff0c;40G的空间&a…

Linux网络-小结

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注我&#xff0c;我尽量把自己会的都分享给大家&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux服务器作为一个常用的网络服务器&#xff0c;主要的作用就是向客户端提供网络…

【Python】数据类型之字符串

本篇文章将继续讲解字符串其他功能&#xff1a; 1、求字符串长度 功能&#xff1a;len(str) &#xff0c;该功能是求字符串str的长度。 代码演示&#xff1a; 2、通过索引获取字符串的字符。 功能&#xff1a;str[a] str为字符串&#xff0c;a为整型。该功能是获取字符…

Java语言程序设计——篇十一(4)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

嵌入式初学-C语言-练习三

#部分题目可能在之前的博客中有&#xff0c;请谅解&#xff0c;保证常见题型均被发出# 1.计算n以内所有正奇数的和 ? n值通过键盘输入 代码&#xff1a; 1 /*2 需求&#xff1a;计算n以内所有正奇数的和 ? n值通过键盘输入3 */4 #include <stdio.h>5 6 int main()7 …

HarmonyOS NEXT——奇妙的调用方式

注解调用一句话总结Extend抽取特定组件样式、事件&#xff0c;可以传递参数Style抽取公共样式、事件&#xff0c;不可以传递参数Builder抽取结构、样式、事件&#xff0c;可以传递参数BuilderParams自定义组件中传递UI组件多个BuilderParams自定义组件中传递多个UI组件 Extend…

【练习】使用DevEco Studio编写计数器案例

效果展示 默认状态 点击加号 点击减号 知识点 类型转换&#xff08;数字 和 字符串&#xff09; 字符串转数字 方法说明例子Number()字符串 直接转数字&#xff0c;转换失败返回NaN&#xff08;字符串包含非数字&#xff09; let str1: string 1.1 console.log(Number(str1)…

数论——线性同余方程、扩欧求解线性同余方程、线性组合、原根求解

线性同余方程 线性同余方程是形如 的方程&#xff0c;其中a 、b、m 为给定的整数&#xff0c;x 是未知整数。 扩欧求解线性同余方程 void mod_slover(int a, int b, int n) {int d, x, y, x0;d extend_gcd(a, n, x, y);if (b % d ! 0)cout << "no answer";…

Linux系统驱动(二)字符设备驱动

文章目录 一、ioctl函数&#xff08;一&#xff09;函数格式&#xff08;二&#xff09;ioctl命令码的组成1. 命令码的组成2. 自己封装命令码2. 内核提供了封装命令码的宏 &#xff08;三&#xff09;使用示例1. 驱动2. 应用 一、ioctl函数 Linux内核开发者想要将数据的读写和…

LabVIEW与CANopen实现自动化生产线的设备控制与数据采集

在某工厂的自动化生产线上&#xff0c;多个设备通过CANopen网络进行通信和控制。这些设备包括传感器、执行器和PLC&#xff0c;它们共同负责监测和控制生产过程中的关键参数&#xff0c;如温度、压力、速度等。为了实现对整个生产线的集中监控和管理&#xff0c;工厂决定使用La…

计算机毕业设计选题推荐-校园服务系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

小程序开发_02项目构成

一、项目的基本结构 二、小程序的页面组成部分 三、json配置文件 ① project.config.json文件 作用&#xff1a;项目的配置文件&#xff0c;用来记录对小程序开发工具所作的个性化配置 ② sitemap.json 作用&#xff1a;是否允许被微信引擎搜索,不希望被搜索dis ③ app.jso…