【C++】C++11的新特性

文章目录

  • 1. C++11简介
  • 2. 统一的列表初始化
    • 2.1 {}统一初始化
    • 2.2 std::initializer_list
  • 3. 声明的新方式和范围for循环
    • 3.1 decltype
    • 3.2 auto&nullptr&范围for循环
  • 4. STL的变化
    • 4.1 新容器
    • 4.2 新接口

1. 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++11中,对于所有的类型(包括自定义类型和内置类型)都提供了一种统一的初始化方式:使用大括号括起来的列表(初始化列表)

  • 在使用初始化列表的时候可以添加等号,也可以不添加等号
void Test1()
{//C++98支持的初始化方式int x1 = 1;//C++11支持的初始化方式int x2{ 2 };int arr1[] = { 1,2,3,4,5 };int arr2[5]{ 0 };//这种初始化方式也可以应用于new表达式中int* pa = new int[5] {1, 2, 3, 4, 5};
}
  • 同时,这种初始化也可以应用于自定义类型(类)中
void Test2()
{Date d1(2023, 1, 1);//之前的创建方式//C++11支持的列表初始化,这里会调用构造函数初始化Date d2{ 2023, 1, 2 };Date d3 = { 2023, 1, 3 };//同样支持new表达式Date* pd = new Date[3]{ {2023,1,4}, {2023,1,5}, {2023,1,6} };
}

2.2 std::initializer_list

那么列表初始化是怎么实现的呢?这就要提到initializer_list

介绍文档:cplusplus.com/reference/initializer_list/initializer_list/

initializer_list是什么类型呢?

image-20230705213425991

可以看到initializer_list是一个类模板。

事实上,initializer_list是非常高效的,因为它的内部并不负责保存初始u话列表中的元素拷贝,只是存储了列表中元素的引用

举个例子:

//不能这样使用initializer_list,因为a,b在返回时并没有被拷贝
initializer_list<int> func()
{int a = 1, b = 2;return { a, b };
}

所以我们应当把initializer_list看做保存对象的引用,并在它持有对象的生存期结束之前完成传递。

initializer_list的使用场景

  • 作为构造函数的参数,使初始化容器对象更加方便
  • 作为operator=的参数,使类支持大括号赋值

这里以我们之前实现的vector为例,做一个模拟实现,让vector也能够支持{}初始化和赋值

vector(std::initializer_list<T> l)//初始化列表初始化
{_start = new T[l.size()];_finish = _start + l.size();_endOfStorage = _start + l.size();iterator vit = _start;for (auto& e : l){*vit++ = e;}
}
vector<T>& operator= (std::initializer_list<T> l)//初始化列表的赋值重载
{vector<T> tmp(l);swap(tmp);return *this;
}

3. 声明的新方式和范围for循环

C++11也提供了很多种简化的声明方式,尤其是在使用模板的时候用处很大。

3.1 decltype

关键字decltype能够将变量的类型声明为表达式的指定类型

在之前的时候,我们想知道一个变量的类型,采用的方式是typeid().name的方式,但是这种方式返回的是一个string,没有办法通过这种方式直接声明新的变量,但是使用decltype就可以。

// decltype的一些使用使用场景
template<class T1, class T2>
void F(T1 t1, T2 t2)
{decltype(t1 * t2) ret;cout << typeid(ret).name() << endl;
}
void Test5()
{const int x = 1;double y = 2.2;decltype(x * y) ret; // ret的类型是doubledecltype(&x) p; // p的类型是int*cout << typeid(ret).name() << endl;cout << typeid(p).name() << endl;F(1, 'a');
}

3.2 auto&nullptr&范围for循环

关于这些知识,在博主之前的博客【C++】初识C++2(内联函数&auto关键字&范围for循环&nullptr)中有详细介绍,有感兴趣的小伙伴可以去看看,这里就不赘述了。

4. STL的变化

4.1 新容器

image-20230706001550520

上图中用红色方框框起来的就是C++11的新增容器,其中unordered系列容器在之前的博客中已经有过讲解【C++】哈希——unordered系列容器&哈希概念&哈希冲突,感兴趣的小伙伴可以去看一看,这里同样就不过多赘述了。

然后就是array和forword_list,实际上着两个容器不经常使用。

array主要对标的用法就是int arr1[5] = {0}<==>array<int, 5> arr2

void Test6()
{int arr1[5] = { 0 };array<int, 5> arr2 = { 0 };
}

二者的唯一区别就是array容器对数组越界的检查更为严格,但是在实际使用过程中,很少用到。

forword_list实际上就是一个单链表,只能进行单项操作,相对于list只是在每个元素上减少了一个指针的大小。

关于这两个容器,就不进行过多的介绍了,这里附上使用文档 array forword_list

4.2 新接口

如果再去仔细看看,就会发现每个容器中都增加了一些C++11 的方法,但是其实我们都很少用到,比如提供了cbegin和cend方法用于返回const迭代器等,但是实际上意义不大,因为begin和end也实现了const版本的函数重载,只是新增的接口让使用看起来更加的规范。

image-20230706002948397

除了迭代器之外,这里还增加了emplaceemplace_back接口,这些是插入函数的右值引用版本,这些接口的意义就是能够提高一点效率,具体提高效率的原因是右值引用,关于右值引用我们下一节再说。


本节完……

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

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

相关文章

MySQL中这些关键字的用法,佬们get到了嘛

前言&#xff1a; 最近粉丝问了一个问题&#xff0c;是关于Limit分页的用法&#xff0c;他没有理解清楚&#xff0c;因此本篇文章主要讲解MySQL的关键字的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。 如果文章有什么需要改进的地方欢迎大佬提出&#xff0c…

【Unity】HyBridCLR初探

完成目标: 创建热更新程序集加载热更新程序集,并执行其中热更新代码,打印 Hello, HybridCLR修改热更新代码,打印 Hello, World准备环境​ 安装Unity HybridCLR也支持2019.4.x,但新手请先按照下面要求跑通流程后,再根据安装HybridCLR文档尝试2019.4.x。 安装 2020.3.26+…

基本介绍实施工程师,以及实施工程师在软件开发的作用

一.软件实施介绍 1.什么是软件实施&#xff1f; 软件实施是指将软件开发完成后&#xff0c;按照计划进行部署和安装&#xff0c;使软件能够在目标环境中正常运行的过程。下面是软件实施的一般步骤&#xff1a; 1. 规划和准备&#xff1a;确定实施的范围、目标和计划&#xff0…

Oracle中的连接方式

Oracle中的连接方式 对于数据库中表与表之间的连接&#xff08;内连接、外连接&#xff09;都可以看成集合之间的运算操作。 内连接 select * from a_table a inner join b_table b on a.id b.id; 相当于求两个集合中满足条件的结果&#xff0c;即交集。 外连接 左/外连接&a…

清华青年AI自强作业hw5:基于CNN实现CIFAR10分类任务

清华青年AI自强作业hw5&#xff1a;基于CNN实现CIFAR10分类任务 简述作业实现遇到的问题相关链接 一起学AI系列博客&#xff1a;目录索引 简述 hw5作业为利用深度卷积神经网络实现CIFAR_10数据集十分类问题&#xff0c;帮助理解CNN的前向传播结构。 CIFAR-10是一个常用的彩色图…

能够辅助用户分类管理个人任务的备忘录哪款比较好?

当我回忆起自己曾经忙碌的日子&#xff0c;我意识到在处理多种事务时&#xff0c;一个高效的分类管理系统是多么的重要。在那段时间里&#xff0c;我不仅要应对工作上的各种任务&#xff0c;还要处理个人事务和日常琐事。随着任务的增加&#xff0c;我发现自己越来越难以有效地…

基于深度学习的高精度红外行人车辆检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度红外行人车辆检测识别系统可用于日常生活中或野外来检测与定位红外行人车辆目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的红外行人车辆目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系…

Tomcat部署及优化

一、Tomcat概述1.1 Tomcat介绍1.2 servlet介绍1.3 JSP介绍 二、Tomcat核心组件2.1 Tomcat三大容器2.2 Tomcat功能组件结构2.2.1 Container结构分析 2.3 Tomcat处理请求过程 三、Tomcat服务部署3.1 关闭防火墙&#xff0c;将安装 Tomcat 所需软件包传到/opt目录下3.2 安装JDK3.3…

【Web3】认识以太坊钱包

目录 区块链钱包概念 密码 私钥 Private Key 公钥Public Key Keystore 助记词 Mnemonic 如何解锁账户 区块链钱包概念 钱包用来存钱的&#xff0c;在区块链中&#xff0c;我们的数字资产都会对应到一个账户地址上&#xff0c; 只有拥 有账户的钥匙&#xff08;私钥&…

【Java可执行命令】(五)打包部署工具 jar:深入解析应用程序打包、分发和部署工具jar ~

Java可执行命令详解之jar 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法格式&#xff1a;创建jar文件3.1.1 参数&#xff1a;-cf3.1.2 参数&#xff1a;-tf3.1.3 参数&#xff1a;-i3.1.4 参数&#xff1a;-v3.1.5 参数&#xff1a;-e 3.2 运行jar文件 4️⃣ 应用场景5️⃣ 注…

fdisk和df -h的区别以及如何看懂和提取信息

前几天要查看linux系统磁盘大小&#xff0c;但是发现fdisk和df -h出来的大小和信息不一样&#xff0c;了解了一下linux的磁盘分区和内存大小&#xff0c;查阅了相关资料&#xff0c;总结以下信息&#xff1a; 一、相关理念 在计算机中&#xff0c;存放信息的主要存储设备就是…

c++摘花生

先看题目&#xff1a; Hello Kitty想摘点花生送给她喜欢的米老鼠。 她来到一片有网格状道路的矩形花生地(如下图)&#xff0c;从西北角进去&#xff0c;东南角出来。 地里每个道路的交叉点上都有种着一株花生苗&#xff0c;上面有若干颗花生&#xff0c;经过一株花生苗就能摘…