C++第四十一弹---C++11新特性深度解析:让你的代码更现代、更高效(上)
创始人
2024-09-25 22:24:33
0

 ✨个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】

目录

1. C++11简介

2. 统一的列表初始化

2.1 {}初始化

2.2 std::initializer_list

3. 声明

3.1 auto

3.2 decltype

3.3 nullptr

3.4 STL中一些变化


1. C++11简介

阶段内容
C with
classes
类及派生类、公有和私有成员、类的构造和析构、友元、内联函数、赋值运算符
重载等
C++1.0添加虚函数概念,函数和运算符重载,引用、常量等
C++2.0更加完善支持面向对象,新增保护成员、多重继承、对象的初始化、抽象类、静
态成员以及const成员函数
C++3.0进一步完善,引入模板,解决多重继承产生的二义性问题和相应构造和析构的处
C++98C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美
国标准化协会认可,以模板方式重写C++标准库,引入了STL(标准模板库)
C++03C++标准第二个版本,语言特性无大改变,主要:修订错误、减少多异性
C++05C++标准委员会发布了一份计数报告(Technical Report,TR1),正式更名
C++0x,即:计划在本世纪第一个10年的某个时间发布
C++11增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循
环、auto关键字、新容器、列表初始化、标准线程库等
C++14对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表
达式,auto的返回值类型推导,二进制字面常量等
C++17在C++11上做了一些小幅改进,增加了19个新特性,比如:static_assert()的文
本信息可选,Fold表达式用于可变的模板,if和switch语句中的初始化器等
C++20自C++11以来最大的发行版,引入了许多新的特性,比如:模块(Modules)、协
程(Coroutines)、范围(Ranges)、概念(Constraints)等重大特性,还有对已有
特性的更新:比如Lambda支持模板、范围for支持初始化等
C++23制定ing



在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官网icon-default.png?t=N7T8https://en.cppreference.com/w/cpp/11小故事:

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中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。比如:

// 1、{}初始化 struct Point { 	int _x; 	int _y; }; int main() { 	// C语言中支持数组使用{}花括号初始化 	int array1[] = { 1,2,3,4,5 }; 	int array2[5] = { 0 }; 	int array3[5]{ 0 };// 可以不加=  	// C语言中结构体支持使用{}初始化 	Point p = { 1,2 };  	return 0; }

测试结果 

C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自
定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

代码演示

struct Point { 	int _x; 	int _y; }; int main() { 	int x1 = 1; 	int x2{ 2 }; 	int array1[]{ 1, 2, 3, 4, 5 }; 	int array2[5]{ 0 }; 	Point p{ 1, 2 }; 	// C++11中列表初始化也可以适用于new表达式中 	int* pa = new int[4] { 0 }; 	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++11之前,旧的方式 	// C++11支持的列表初始化,这里会调用构造函数初始化 	Date d2{ 2022, 1, 2 }; 	Date d3 = { 2022, 1, 3 }; 	return 0; }

测试结果 

2.2 std::initializer_list


std::initializer_list的介绍文档:

initializer_list文档icon-default.png?t=N7T8https://cplusplus.com/reference/initializer_list/initializer_list/

std::initializer_list是什么类型:

代码演示

int main() {     auto il = { 1,2,3 };     initializer_list il2 = { 4,5,6 };     cout << typeid(il).name() << endl;     return 0; }

测试结果 

std::initializer_list使用场景:
std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator=的参数,这样就可以用大括号赋值。

代码演示

int main() { 	vector v1(10,1); 	// 构造 	vector v2({ 1,2,3,4,5 }); 	// initializer_list 	vector v3 = { 1,3,5,7,9 }; 	vector v4{ 2,4,6,8,10 };  	pair kv1("insert","插入"); 	pair kv2("left", "左边");  	map dict1 = { kv1,kv2 };  	// 1、pair多参数隐式类型转换 	// 2、initializer_list构造 	map dict = { {"right","右边"},{"string","字符串"} }; 	return 0; }

测试结果 

3. 声明


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

3.1 auto


C++98auto是一个存储类型的说明符表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。C++11中废弃auto原来的用法,将其用于实现自动类型推断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初始化值的类型。

代码演示

int main() { 	int i = 10; 	auto p = &i; 	// 函数指针,将函数地址传给pf 	auto pf = strcpy; 	cout << typeid(p).name() << endl; 	cout << typeid(pf).name() << endl; 	map dict = { {"sort", "排序"}, {"insert", "插入"} }; 	// map::iterator it = dict.begin(); 	// 原本类型如上,很长,使用auto可以自动推导类型,且很短 	auto it = dict.begin(); 	return 0; }

测试结果 

注意:auto有一个缺陷,当使用auto为函数的返回类型时,代码可读性不强,因为函数内部可能嵌套了很多函数。

auto func1() { 	list lt; 	auto ret = lt.begin(); 	// ret为链表迭代器的第一个位置,不能够快速确定返回类型是什么 	return ret; }

 如上代码,只使用了一个函数就很难确定func1函数的返回类型是什么。

3.2 decltype


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

代码演示

template class B { public: 	T* New(int n) 	{ 		return new T[n]; 	} }; auto func1() { 	list lt; 	auto ret = lt.begin(); 	// ret为链表迭代器的第一个位置,不能够快速确定返回类型是什么 	return ret; } int main() { 	list::iterator it; 	// typeid推出是一个单纯的字符串 	cout << typeid(it).name() << endl; 	 不能用来定义对象 	//typeid(it).name() it1; 	// 可以用来定义对象 	decltype(it) it2; 	cout << typeid(it2).name() << endl; 	auto it3 = it2; 	cout << typeid(it3).name() << endl;     // 不知道func1函数返回什么类型,但是可以通过返回的类型实例化对象 	auto ret = func1(); 	B bb1; 	map dict = { {"string","字符串"},{"left","左边"} }; 	auto it4 = dict.begin(); 	B bb2; 	// 与上面代码实例化类型一样,但是长度更长 	B::iterator> bb3; 	return 0; }

测试结果 

3.3 nullptr


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

#ifndef NULL     #ifdef __cplusplus         #define NULL 0     #else         #define NULL ((void *)0)     #endif #endif

3.4 STL中一些变化


新容器


用橘色圈起来是C++11中的一些几个新容器,但是实际最有用的是unordered_map和
unordered_set。这两个我们前面已经进行了非常详细的讲解,其他的uu了解一下即可。

容器中的一些新方法


如果我们再细细去看会发现基本每个容器中都增加了一些C++11的方法,但是其实很多都是用得
比较少的。
比如提供了cbegin和cend方法返回const迭代器等等,但是实际意义不大,因为begin和end也是
可以返回const迭代器的,这些都是属于锦上添花的操作。
实际上C++11更新后,容器中增加的新方法最后用的插入接口函数的右值引用版本

但是这些接口到底意义在哪?网上都说他们能提高效率,他们是如何提高效率的?
请看下面的右值引用和移动语义章节的讲解。另外emplace还涉及模板的可变参数,也需要再继
续深入学习后面章节的知识。 

相关内容

热门资讯

笔记本xp系统安装安卓系统,轻... 你有没有想过,在你的老式笔记本上安装一个全新的操作系统呢?想象那台陪伴你多年的老笔记本,突然焕发出青...
安卓操作系统吃内存,安卓操作系... 手机里的安卓操作系统是不是让你感觉内存越来越不够用了?别急,今天就来给你好好分析分析这个让人头疼的问...
王者号ios系统怎么转安卓系统... 你是不是也和我一样,对王者荣耀这款游戏爱得深沉呢?尤其是当你发现某个英雄在安卓系统上玩起来更加得心应...
战神遗迹安卓苹果系统,探索神秘... 亲爱的玩家们,你是否曾在游戏中追寻那些传说中的神秘遗迹?今天,我要带你走进一个充满传奇色彩的领域——...
几何a安卓系统升级,畅享智能出... 你有没有发现,你的几何A最近变得聪明多了?没错,就是那个陪伴你上下班的几何A,它悄悄地升级了安卓系统...
系统最清爽的安卓手机,探索系统... 你有没有想过,拥有一部系统最清爽的安卓手机,就像是拥有了夏日里的一阵清风,让人心情舒畅,操作顺畅?今...
安卓10系统严重有问题,揭秘严... 最近你的安卓手机是不是也遇到了一些让人头疼的问题呢?别急,让我来给你一探究竟,看看安卓10系统到底有...
安卓系统闽政通打不开,“闽政通... 最近是不是有不少小伙伴在使用安卓手机时遇到了一个让人头疼的问题——闽政通打不开?别急,今天就来给你详...
安卓系统有指纹忘了图案,解锁攻... 手机解锁方式千千万,指纹解锁和图案解锁可谓是其中的佼佼者。但有时候,指纹解锁用得太多,导致忘记了图案...
QQ飞车安卓系统怎么换苹果系统... 你是不是也和我一样,对QQ飞车这款游戏爱得深沉呢?不过,最近我发现了一个超级有趣的问题:怎么把QQ飞...
安卓可冻结的系统文件,那些不可... 你知道吗?在安卓的世界里,有一些神秘的文件,它们就像隐藏在深宫中的宝贝,让人既好奇又敬畏。这些文件,...
安卓系统安装需要备份吗,关键指... 你最近是不是在准备给安卓手机升级系统或者安装新应用呢?别急,别急,在这之前,有个小细节你得注意一下—...
高仿ios的安卓系统,带你领略... 你有没有想过,为什么安卓手机那么受欢迎,却还是有人对iOS系统念念不忘呢?其实,现在市面上就有一种神...
安卓系统全能播放器,尽享视听盛... 你有没有发现,手机里总是装满了各种音乐、电影、电视剧,但是找到一个能让你一次性搞定所有播放需求的软件...
在哪里安装安卓系统好,安卓系统... 你有没有想过,为什么安卓系统这么受欢迎呢?它那强大的兼容性和丰富的应用生态,简直让人爱不释手。但是,...
如何自己提升安卓系统,自我提升... 你有没有发现,随着智能手机的普及,安卓系统已经成为了我们生活中不可或缺的一部分呢?但是,你是否想过,...
安卓子系统内存不足,应对策略与... 手机突然卡顿,是不是安卓子系统内存不足在作怪?别急,让我带你一探究竟,揭开这个问题的神秘面纱!一、安...
一鸣安卓系统如何安装,轻松上手... 你有没有想过,给你的安卓手机换换口味?别看它现在运行得风生水起,偶尔来点新鲜玩意儿,岂不是更带劲?今...
安卓操作系统的归属,源自谷歌的... 你有没有想过,那个陪伴你每天刷抖音、玩游戏、处理工作的安卓操作系统,它究竟是谁的孩子呢?今天,就让我...
安卓启动系统设置界面,揭秘安卓... 你有没有发现,每次打开安卓手机,那启动系统设置界面就像是个神秘的宝箱,里面藏着无数的小秘密?今天,就...