c++ - 第19节 - c++11

news2024/9/28 5:28:45

1.C++11简介

c++11简介:
在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于C++03(TC1)主要是对C++98标准中的漏洞进行修复,语言的核心部分则没有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑,第二个真正意义上的标准珊珊来迟。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛化和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,公司实际项目开发中也用得比较多,所以我们要作为一个重点去学习。C++11增加的语法特性篇幅非常多,我们这里没办法一一讲解,所以本节课程主要讲解实际中比较实用的语法。
c++11官网介绍: C++11 - cppreference.com
小故事:
1998年是C++标准委员会成立的第一年,本来计划以后每5年视实际需要更新一次标准,C++国际标准委员会在研究C++03的下一个版本的时候,一开始计划是2007年发布,所以最初这个标准叫C++07。但是到06年的时候,官方觉得2007年肯定完不成C++07,而且官方觉得2008年可能也完不成。最后干脆叫C++0x。x的意思是不知道到底能在07还是08还是09年完成。结果2010年的时候也没完成,最后在2011年终于完成了C++标准。所以最终定名为C++11。


2.统一的列表初始化

2.1.{}初始化

在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。比如:
struct Point
{
	int _x;
	int _y;
};
int main()
{
	int array1[] = { 1, 2, 3, 4, 5 };
	int array2[5] = { 0 };
	Point p = { 1, 2 };
	return 0;
}
C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。
struct Point
{
	int _x;
	int _y;
};
int main()
{
	int x1 = 1;   //c++98
	int x2 = { 1 };   //c++11
	int x3{ 1 };   //c++11

	int array1[] = { 1, 2, 3, 4, 5 };   //c++98
	int array2[]{ 1, 2, 3, 4, 5 };   //c++11
	int array3[5] = { 0 };   //c++98
	int array4[5]{ 0 };   //c++11

	Point p = { 1, 2 };   //c++98
	Point p{ 1, 2 };   //c++11

	// C++11中列表初始化也可以适用于new表达式中
	int* pa1 = new int(0);   //c++98,c++98new空间只支持new一个数据空间并初始化
	int* pa2 = new int[4]{ 0 };   //c++11,c++11new空间支持直接对多个new数据空间初始化
	int* pa3 = new int[4]{ 1,2,3,4 };   //c++11,c++11new空间支持直接对多个new数据空间初始化

	return 0;
}

创建对象时也可以使用列表初始化方式调用构造函数初始化
class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2022, 1, 1);   //c++98
	// C++11支持的列表初始化,这里会调用构造函数初始化
	Date d2 = { 2022, 1, 3 };   //c++98
	Date d3{ 2022, 1, 2 };   //c++11

	Date* p1 = new Date(1, 2, 3);   //c++98,c++98new空间只支持new一个数据空间并初始化
	Date* p2 = new Date[3]{ {2022,1,1}, {2022,1,1} ,{2022,1,1} };   //c++11,c++11new空间支持直接对多个new数据空间初始化

	return 0;
}

注:其实c++11支持{}初始化本质上是为了支持new[]的多数据初始化和容器的多数据初始化。

创建容器对象时也可以使用列表初始化方式进行初始化
class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	vector<int> v1 = { 1, 2, 3, 4, 5 };
	vector<int> v2 { 1, 2, 3, 4, 5 };
	vector<Date> v3 = { { 2022, 1, 1 }, { 2022, 1, 1 }, { 2022, 1, 1 } };
	list<int> lt1{ 1, 2, 3 };
	set<int> s1{ 3, 4, 5, 6, 3 };
	map<string, string> dict = { { "string", "字符串" }, { "sort", "排序" } };

	return 0;
}

2.2.{}初始化的实现

对于所有的内置类型和用户自定义的类型,编译器通过自动转换如下图所示(内置类型自动转换方式相同),这样就天然支持列表初始化方式进行初始化。

注:这里代码Date d2={2022,1,3}是一种隐式类型的转换(隐式类型的转换是针对单参数的构造函数,这里虽然不是单参数的构造函数但是数据用{}括起来可以认为整体是单参数的),编译器首先利用{2022,1,3}构造一个Date类型的临时对象,然后用该临时对象拷贝构造给d2,编译器进行优化会直接调用Date的构造函数使用{2022,1,3}对d2进行构造。

对于STL库中的容器类型,c++11可以使用列表初始化方式对容器对象进行初始化,其实现是借助c++11新增容器initializer_list。

initializer_list类的文档介绍:initializer_list - C++ Reference (cplusplus.com)

我们使用的{}初始化列表会被编译器识别成initializer_list,{}初始化列表里面的常量内容会存储在容器initializer_list中,如下图一所示。initializer_list容器中有迭代器,initializer_list中的迭代器只能读不能写,如下图二所示,initializer_list容器中begin和end函数返回的是const修饰的指针类型,通过迭代器可以读取initializer_list容器中的数据,如下图三所示。

c++11中,STL库的各种容器中新增了一个参数类型为initializer_list的构造函数,如下图所示分别是vector、map中该新增的构造函数,各类容器在该新增的构造函数中接收initializer_list容器中的数据也就是{}初始化列表中的数据进行初始化工作。

容器中数据初始化工作一般可分为两步,首先创建空间,然后通过迭代器遍历构造函数的initializer_list类型形参对象数据,每个数据进行insert或push_back插入操作即可。vector中该构造函数初始化工作的实现代码如下图所示。

注:

1.这里vector<int> v1={1,2,3,4}可以认为是隐式类型的转换,先通过{1,2,3,4}构造了一个vector对象,然后通过该对象拷贝构造给v1对象,编译器优化成直接用{1,2,3,4}对v1进行构造。

2.如下图所示,这里的代码v1={10,20,30}也是隐式类型的转换,首先通过{1,2,3,4}构造了一个vector对象,然后通过该对象调用赋值运算符重载函数赋值给v1对象。

3.这里我们可以看出只需要给容器的构造函数增加一个参数类型为initializer_list的构造函数,构造函数内进行开空间+数据插入的初始化工作,即可实现容器的{}初始化功能。

补充内容:STL库中每个容器的插入函数也有参数类型为initializer_list的版本,如下图一所示,那么我们使用插入函数一次就可以插入多个数据,如下图二所示。


3.声明

c++11 提供了多种简化声明的方式,尤其是在使用模板时。

3.1.auto

在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。 C++11中废弃auto原来的用法,将其用于实现自动类型推断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。
int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcpy;
	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;

	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
	//map<string, string>::iterator it = dict.begin();
	auto it = dict.begin();

	return 0;
}

3.2.decltype

关键字decltype将括号内变量的类型声明为表达式指定的类型。

3.3.nullptr

由于C++中NULL被定义成0,这样就可能回带来一些问题,因为0既能表示指针常量,又能表示整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。
#ifndef NULL
#ifdef __cplusplus
#define NULL   0
#else
#define NULL   ((void *)0)
#endif
#endif


4.范围for循环

范围for我们在前面的博客中已经进行了详细的讲解(参考博客c++入门),这里就不再赘述。


5.智能指针

智能指针部分内容较多,后面会专门写一个博客来介绍智能指针。


6.STL中一些变化

新容器:
用橘色圈起来是C++11中新增的几个新容器,但是实际最有用的是unordered_map和
unordered_set。这两个我们前面已经进行了详细的讲解,array(前面讲过,与静态数组相似)和forward_list(单链表)大家了解一下即可。
容器中的一些新方法:
如果我们再细细去看会发现基本每个容器中都增加了一些C++11的方法,但是其实很多都是用得比较少的。
比如提供了cbegin和cend方法返回const迭代器等等,但是实际意义不大,因为begin和end也是可以返回const迭代器的,这些都是属于锦上添花的操作。
实际上C++11更新后,每个容器的插入函数接口都新增了右值引用的版本,如下图所示。

这些容器的插入函数新增的右值引用版本到底意义在哪?网上都说他们能提高效率,他们是如何提高效率的?下面第7节右值引用和移动语义部分我们会进行解答。


7.右值引用和移动语义

7.1.左值引用和右值引用

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

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

相关文章

Pycharm打开Project(工程)时停留在preparing workspace时间过长,导致打开很慢的解决方法...

Pycharm打开Project(工程)时停留在preparing workspace时间过长,导致打开很慢的解决方法… 昊虹君用Pycharm进行Python的开发&#xff0c;一直用得好好的&#xff0c;也没作过什么异常操作&#xff0c;但是从上星期开始&#xff0c;打开Project(工程)时停留在preparing worksp…

【王道操作系统】2.1.1 进程的定义、特征、组成、组织

进程的定义、特征、组成、组织 文章目录进程的定义、特征、组成、组织1.进程的定义2.进程的特征3.进程的组成4.进程的组织1.进程的定义 程序的概念&#xff1a; 进程的概念&#xff1a; 进程和程序的区别和联系&#xff1a; 区别&#xff1a; 进程是动态的&#xff0c;程序是静…

Linux系统下crond任务调度指令的常见用法

Linux系统下crond任务调度指令的常见用法 任务调度 任务调度是指系统在某个时间执行的特定的命令或程序。任务调度分类:1)系统工作:有些重要的工作必须周而复始地执行。如病毒扫描等;2)个别用户工作:个别用户可能希望执行某些程序&#xff0c;比如对mysql数据库的备份。 基本语…

【攻防世界】网鼎杯2018 Web fakebook

学web总是能让我学到新的知识&#xff0c;很开心&#xff0c;很有趣&#xff0c;很好玩 打开题目 一个登录按钮&#xff0c;一个注册按钮&#xff0c;其余没有什么发现&#xff0c;对于web来说&#xff0c;常规先测试一下robots.txt文件 果然又发现&#xff0c;有一个bak文件…

opencv-python常用函数解析及参数介绍(二)——图像填充与图像融合

1.图像填充 函数及参数介绍 在opencv中使用cv2.copyMakeBorder可以进行图像的边界填充&#xff0c;需要的参数为(img, top_size, bottom_size, left_size, right_size, borderType&#xff09;&#xff0c;即&#xff08;图片&#xff0c;上侧填充值&#xff0c;下侧填充值&a…

【数据结构与算法】KMP算法

文章目录前言一 .KMP的来历二.KMP解决的问题1.引入2.定义的引入1.字符串前缀2.字符串后缀3.最长相等前后缀3.核心思想三.next/prefix1.next的含义定义规律2.next的求取1.准备工作2.思路和图解4.应用前言 在C语言的strcmp的实现过程中&#xff0c;所涉及的算法较为简单&#xff…

Golang - 字符串操作汇总

Golang 字符串操作汇总1 string初始化2 遍历string3 byte & Rune3.1 初始化3.2 byte和rune区别1 string初始化 func newString() {//1. 字符串初始化// 方式一&#xff1a;使用简写声明&#xff0c;带有字符串的变量,支持特殊字符str : "one hello \n world"fmt…

三个月后,快手To B怎么样了?

未来&#xff0c;如何独立作战和走出快手的TOC“客户资源圈”&#xff0c;或将成为快手TOB新的十字路口。 作者|斗斗 编辑|皮爷 出品|产业家 人口红利终结&#xff0c;流量红利终结&#xff0c;超常规的高速增长终结。TOC模式的路越来越难走了。 快手与抖音作为短视频…

光耦特性以及计算

光耦特性 光耦器件电路图 这是我们常用的。光耦器件以及它的连接方式。 左侧R1是我们主要考虑的。 电流最小值是要让LED能够保持发光状态&#xff0c;最大值的话。1.不能让LED烧坏了。2. LED的负极端是单片机的。 这里主要是看引脚灌入电流的最大值。 电气规格 我们看看说…

手机数据包抓包详解

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是手机数据包抓包详解。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1a;严禁对未授权设…

并发编程——6.共享模型之不可变

目录6.共享模型之不可变6.1.日期转换的问题6.1.1.问题提出6.1.2.解决思路——同步锁6.1.3.解决思路——不可变6.2.不可变设计6.3.享元模式6.3.1.简介6.3.2.体现6.3.3.DIY6.4.final 原理6.5.无状态本文笔记整理来自黑马视频https://www.bilibili.com/video/BV16J411h7Rd/?p197&…

Unity脚本(二)

视频教程&#xff1a;https://www.bilibili.com/video/BV12s411g7gU/?share_sourcecopy_web Transform 对象的位置、旋转和缩放 场景中的每个对象都有一个Transform&#xff0c;用于存储和操作对象的位置、旋转和缩放。 每个Transform都可以有一个父级&#xff0c;能够分…

C语言强制类型转换

强制类型转换是把变量从一种类型转换为另一种数据类型。例如&#xff0c;如果您想存储一个 long 类型的值到一个简单的整型中&#xff0c;您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型&#xff0c;如下所示&am…

gitlab-ci.yml关键字(五)tags 、only 、when

tags 使用Tags用于选择Runner的标签列表 我们在创建Runner 时可以给该Runner打上特定的标签&#xff0c;那后续流水线中的job如果需要使用特定标签的Runner执行时&#xff0c;就需要使用tags来标记 比如这里有两个标签的Runner 也可以对当前的runner进行一些配置上的设置 …

2022总结:我是怎样从一个混子到如今小有所成

前言 &#x1f340;作者简介&#xff1a;被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 &#x1f341;个人主页&#xff1a;红中 &#x1f342;抽根烟&#xff0c;吹个牛b(不是 入门 如果硬要问我是在什么时候入门的&#xff0c;那就要说到高一…

MySQL添加用户及用户权限管理

目录 1、用户 <1> 用户信息 <2> 创建用户 <3> 删除用户 <4> 修改用户密码 2、用户权限管理 <1> 查看用户权限 <2> 给用户授权 <3> 回收权限 1、用户 <1> 用户信息 MySQL中的用户&#xff0c;都存储在系统数据库mysq…

机器翻译与数据集

机器翻译指的是将文本序列从一种语言自动翻译成另一种语言。 使用单词级词元化时的词表大小&#xff0c;将明显大于使用字符级词元化时的词表大小。为了缓解这一问题&#xff0c;我们可以将低频词元视为相同的未知词元。 通过截断和填充文本序列&#xff0c;可以保证所有的文…

【LeetCode每日一题】——154.寻找旋转排序数组中的最小值 II

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【题目进阶】九【时间频度】十【代码实现】十一【提交结果】一【题目类别】 二分查找 二【题目难度】 困难 三【题目编号】 154.寻找旋转排序数组中的最小…

windows下OpenCV安装教程以及vs2019配置opencv教程

文章目录一. OpenCV下载二. OpenCV安装及配置三. VS2019项目配置OpenCV一. OpenCV下载 官网地址&#xff1a;Home - OpenCV 下载地址&#xff1a;OpenCV download | SourceForge.net 二. OpenCV安装及配置 双击下载好的安装包进行安装 安装过程实际上是一个解压过程 选择…

java开发机动车考试驾照考试-科一科四考试在线题库系统

简介 本系统主要是进行科一科四考试和练习的网上考试系统&#xff0c;分为A1B1、A2B2、C1C2的科一科四考试系统&#xff0c;当学员点击开始考试&#xff0c;系统将自动生成随机题目100道&#xff08;选择题80道&#xff0c;判断题20道&#xff09;的试卷&#xff0c;考试时间4…