【C++】C++11——简介|列表初始|简化声明|nullptr与范围for|STL中的变化

news2025/1/27 12:39:52

文章目录

    • 一、C++11简介
    • 二、列表初始化
    • 三、简化声明
    • 四、nullptr与范围for
    • 五、STL中一些变化

一、C++11简介

在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了C++98称为C++11之前的最新C++标准名称。不过由于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++98中,标准允许使用花括号{}对数组元素进行统一的列表初始值设定。举个例子:

struct Point
{
	int _x;
	int _y;
};
int main()
{
	Point p1 = { 1,2 };
	int array1[] = { 1,2,3,4,5 };
	int array2[5] = { 0 };
	return 0;
}

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

struct Point
{
	int _x;
	int _y;
};
int main()
{
	Point p1 = { 1,2 };
	int array1[] = { 1,2,3,4,5 };
	//去掉赋值符号

	Point p2{ 2,2 };
	int array2[]{ 1,2,3,4,5 };

	//更加离谱
	int x1 = 1;
	int x2 = { 1 };
	int x3{ 1 };

	return 0;
}

new 表达式初始化时一定不能添加等号:

int* p3 = new int[10];

int* p4 = new int[10]{ 1,2,3,4 };
Point* p5 = new Point[2]{ {1,1},{2,2} };

日期类构造函数初始化:

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(1, 1, 1);//构造函数
	Date d2{ 1,1,1 };
	return 0;
}

对于上面这些都是比较轻松的,更多的在于容器的初始化:

int main()
{
	vector<int> v = { 1,2,3,4,5,6,7,8};
	vector<int> v1 = { 1,2,3,4 };

	list<int> lt = { 1,2 };
	list<int> lt1 = { 1,2,3,4,5,6,7 };
	return 0;
}

vector和list为什么可以这样子初始化,这就要说到一个新的容器了:initializer_list

initializer_list 是一个容器,是 C++11 新增的:

只提供了 begin 和 end 函数,用于迭代器遍历;以及获取容器中的元素个数的 size 函数:

image-20230306234037072

{}的本质就是initializer_list,如果我们使用auto来定义一个变量去接收一个大括号括起来的列表,然后用 typeid(变量名).name() 查看变量的类型,此时会发现该变量的类型就是 initializer_list👇

image-20230306233627590

这个东西到底有什么用:C++98 不支持直接用列表对容器进行初始化,这种初始化方式是在C++11引入initializer_list后才支持的,而这些容器之所以支持使用列表进行初始化,是因为C++11提供了一个构造函数,以initializer_list为参数

看一下C++11vector的构造:

image-20230307123009003

image-20230307124624643

当用列表对容器进行初始化时,会被认为是initializer_list类型,此时不管有多少个值都能够被初始化vector。而我们之前自己实现的vector是无法支持的,现在我们可以为之前自己模拟实现的vector提供一个构造函数:遍历initializer_list 中的元素,然后push_back进要初始化的容器当中:

vector(initializer_list<T> il)
	:_start(nullptr)
	, _finish(nullptr)
	, _endofstorage(nullptr)
{
	typename initializer_list<T>::iterator it = il.begin();
	while (it != il.end())
	{
		push_back(*it);
		++it;
	}
}

三、简化声明

C++11提供了多种简化声明的方式。

1.auto

auto使用的前提是:必须要对auto声明的类型进行初始化,否则编译器无法推导出auto的实际类型。

如果类型过长,比如迭代器的名称,我们就可以使用auto,用于实现自动类型推断

int main()
{
	int x = 0;
	auto y = x;
	cout << typeid(x).name() << endl;
	cout << typeid(y).name() << endl;
	return 0;
}

image-20230307131053460

typeid只能查看类型不能用其结果类定义类型

2.decltype

decltype是根据表达式的实际类型推演出定义变量时所用的类型

template<class T1, class T2>
void F(T1 t1, T2 t2)
{
	decltype(t1 * t2) ret = t1 * t2;
	cout << typeid(ret).name() << endl;
	cout << ret << endl;
}

int main()
{
	int x = 0;
	decltype(x) y;
	cout << typeid(y).name() << endl;

	F(1, 2.2);
}

image-20230307132004655

typeid(变量名).name()的方式只能获取一个变量的类型,但无法获取这个类型去定义变量。而decltype除了能够推演表达式的类型,还能推演函数返回值的类型。


四、nullptr与范围for

  • nullptr

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

#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else  
#define NULL    ((void *)0)
#endif  
#endif  /* NULL */
  • 范围for

C++11中还有范围for,范围for循环后的括号由冒号分为两部分,第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围:

int main()
{
	vector<int> v = { 1,2,3,4,5,6 };
	for (auto& e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

范围for本质上是由迭代器支持的,在代码编译的时候,编译器会自动将范围for替换为迭代器的形式


五、STL中一些变化

C++11中新增了容器,分别是array、forward_list、unordered_map和unordered_set

image-20230308124304812

  • array

array是一个静态数组,即固定大小的数组,没有资格与vector对比:

array有两个模板参数,第一个模板参数代表的是存储的类型,第二个模板参数是一个非类型模板参数,代表数组中存储元素个数

int main()
{
	array<int,10> a1;
	int a2[10];
	a2[11];//没报错
	return 0;
}

array与普通数组的对比:

C语言数组对于越界检查是抽查的,越界可能检查不出来,但是对于array的越界读写都能检查出来的

因为array用一个类对数组做了封装,并且在访问array容器中的元素时会进行越界检查:用[]访问元素时采用断言,调用at成员函数访问元素时采用抛出异常检查。

当然,vector也可以检查出越界的情况,而且array没有初始化,并且与其他容器不同的是,array容器的对象是创建在栈上的,因此array容器不适合定义太大的数组,不如vector

  • forward_list容器

image-20230308132352601

forward_list容器本质就是一个单链表,很少使用:

image-20230308174418028

forward_list只提供了头插头删,不支持尾插尾删,因为单链表在进行尾插尾删时需要先找尾

forward_list提供插入insert_after在指定的元素后面插入一个元素,而不像其他容器是在指定的元素前面插入一个元素,单链表要找到指定元素前一个元素就要重新遍历一遍,删除也是erase_after,也就是删除指定元素后的一个。

所以我们一般还是使用list容器

  • C++11新的接口

C++11给容器都增加了一些新的接口:

最开始说的提供了一个以initializer_list作为参数的构造函数,用于支持列表初始化

比较鸡肋的接口:cbegin 、cend系列,以及缩容接口shrink_to_fit(异地)

比较有用:

移动构造和移动赋值

emplace_xxx插入接口


本篇结束…

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

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

相关文章

Easyrecovery16免费的电脑硬盘恢复数据软件

在我们的日常生活和工作中&#xff0c;很容易发生一些意外情况&#xff0c;比如误删文件。这种情况下&#xff0c;您可能会感到非常困惑和担心&#xff0c;担心文件已经永久丢失&#xff0c;无法恢复。但是&#xff0c;在大多数情况下&#xff0c;即使您误删了文件&#xff0c;…

Nativefier把网页打包成exe

前要&#xff1a; 今天遇到一个需求&#xff0c;之前的应用都是用的h5挂载在企业微信的小应用&#xff0c;但是现在需要电脑运行的exe安装包&#xff01; 所以需要用到nativefier导报工具&#xff1a;nativefier是一个使用electron将网页转换为app的插件&#xff0c;写这篇博客…

二、SpringMVC注解式开发

1. RequestMapping注解 此注解就是来映射服务器访问的路径 可加在方法上,是为此方法注册一个可以访问的名称(路径) 可以加在类上,相当于是包名(虚拟路径),区分不同类中相同的action的名称 可区分get请求和post请求 package com.powernode.controller;import org.springframe…

liunx下安装node exporter

1 建立文件夹 cd /opt mkdir software 下载最新的包&#xff0c;并解压 https://prometheus.io/download/ 下载 curl -LO https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz 3.解压 tar -xvf node_exporter-0.…

Gorm根据关系模型中的属性查询原模型数据

type ExamResult struct {gorm.ModelExamManagementID uintExamManagement ExamManagement json:"examManagement" // 一场考试&#xff0c;其中有试卷&#xff0c;有试题&#xff0c;有试题答案//MarkExamPaperRecord MarkExamPaperRecord //每一场考试对应的结…

测试经理:“你做了三年测试,连服务端的接口测试都不会?”

服务端的接口测试我们一般从功能开始进行测试&#xff0c;比如请求参数和响应参数的校验&#xff0c;业务逻辑或业务规则的校验&#xff0c;数据库操作的校验。 功能正常后会根据需要进行安全相关的检查、性能测试以及系列扩展测试&#xff0c;比如与历史版本的兼容性测试、接…

【微信小程序】-- WXS 脚本(二十九)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

【Java基础】Linux系统

CONTENT一、常用命令时间日期关机&重启登录&注销运行级别找回root用户密码&#xff08;CentOS 7&#xff09;二、文件管理显示当前工作路径显示文件和目录切换目录创建文件&目录删除文件&目录拷贝文件&目录移动文件&目录 / 重命名查找文件&目录查看…

java启动命令中-D和--的区别

目录一、java -D 添加参数二、java -- 添加参数在 SpringBoot 项目中&#xff0c;启动时&#xff0c;通过 -D 或 -- 添加参数&#xff0c;都可以直接覆盖 yml 或 properties 配置文件中的同名配置&#xff0c;如果不存在则相当于添加了一个配置。 一、java -D 添加参数 java -D…

【面试题】三道面试题让你掌握JavaScript中的执行上下文与作用域以及闭包

前言大厂面试题分享 面试题库前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库大家好&#xff0c;笔者呢最近再回顾JavaScript知识时&#xff0c;又看到了JavaScript的一些较为常见的内容&#xff0c;仔细看了之后发现…

1-1 微服务架构概述

文章目录微服务架构概述1-1. 系统进化理论概述集中式系统&#xff1a;分布式系统1-2. 系统进化理论背景1-3. 什么是微服务架构1-4. 微服务架构的优缺点1-5. 为什么选择 Spring Cloud 构建微服务认识 Spring Cloud2-1. Spring Cloud 是什么2-2. Spring Cloud 的版本2-3 Spring C…

2.2操作系统-进程管理:前趋图、前趋图与PV操作

2.1操作系统-进程管理&#xff1a;前趋图\前趋图与PV操作前趋图前趋图与PV操作练习前趋图与PV操作&#xff0c;一般出现了&#xff0c;分值在2~3分左右&#xff0c;技巧性很强。 前趋图 前趋图是为了描述一个程序的各部分间的依赖关系&#xff0c;或者是一个大的计算的各个子…

【c++类与对象 】

目录&#xff1a;前言一、基础引入1.类的定义2.类的权限3.类的封装4.类的实例化5.计算类对象的大小结构体内存对齐规则空类的大小二、this指针this引入this指针的特性经典例题三、类的六个默认成员函数1、构造 && 析构构造函数析构函数2、拷贝 && 赋值拷贝构造…

display:inline-flex使用

凡是使用了display:inline-flex布局的容器&#xff08;不管是行内元素还是块级元素&#xff09;&#xff0c;将会变为弹性容器&#xff0c;它的宽高都将可以被设置&#xff0c;并且该容器整体对外表现为一个行内块元素。 span也可以设置宽高&#xff0c;并且div和span它们都没有…

【C++】缺省参数函数重载

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录前言一、缺省参数1.1 缺省参数的概念1…

关于new和delete的一些思考,为什么不能在析构函数中调用delete释放对象的内存空间,new和delete的原理

最近在写代码的时候&#xff0c;觉得每次new出来的对象都需要去delete好麻烦&#xff0c;于是直接把delete写到了析构函数中&#xff0c;在析构函数里面写了句delete this&#xff0c;结果调用析构函数的时候死循环了&#xff0c;不是很理解原因&#xff0c;于是去研究了一下。…

盘点全球10大女性技术先驱

盘点全球10大女性技术先驱 人们普遍认为技术是男性主导的领域&#xff0c;但事实&#xff0c;技术或编程与性别无关&#xff0c;几乎任何人都可以成为技术大神。已经有很多案例证明女性同样可以在技术领域施展才能。在女神节来临之际&#xff0c;我为大家盘点一下为编程做出卓越…

AB测试——流程介绍(定义问题和指标选取)

前言&#xff1a; 作为AB测试的学习记录&#xff0c;本文主要介绍了AB测试的基本流程&#xff0c;以及指标类型和如何选取合适指标。 相关文章&#xff1a;AB测试——原理介绍 AB测试的基本流程是什么&#xff1f; AB测试&#xff08;也称为分流测试&#xff09;是一种常用的实…

visual studio的team使用问题小结

visual studio的team使用问题小结一、visual studio&#xff08;2017&#xff09;默认浏览器打开team任务和bug二、visual studio&#xff08;2017&#xff09;上传team时&#xff0c;文件超过一万个会上传失败。三、visual studio&#xff08;2017&#xff09;拉取team代码时&…

C++面向对象编程之二:构造函数、拷贝构造函数、析构函数

构造函数和析构函数C利用构造函数和析构函数&#xff0c;完成对象的初始化和清理工作。对象的初始化和清理工作&#xff0c;是编译器强制我们要做的事情&#xff0c;如果我们不提供构造函数和析构函数&#xff0c;编译器会提供3个函数&#xff1a;默认无参构造函数默认拷贝构造…