【C++学习】C++11新特性(第一节)

news2025/6/22 15:00:18

在这里插入图片描述

文章目录

  • 一.文章前言
  • 二.C++11新特性
    • 一.统一的列表初始化
    • 二.std::initializer_list
    • 三.声明
    • 四.decltype关键字
    • 五.nullptr
    • 六.新增加容器---静态数组array、forward_list以及unordered系列
      • 6.1unordered_map与unoredered_set
      • 6.2array
      • 6.3 forward_list(单链表)

一.文章前言

C++11文档链接:link

2011年之前,C++98(C++03)称为C++11之前的最新C++标准名称。相比于C++98/03,C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序员的开发效率,C++11的新特性将会分为三个文章进行讲解,这是第一节。

二.C++11新特性

一.统一的列表初始化

  • 在C++98中,标准允许使用花括号{ }对数组或者结构体元素进行统一的列表初始值设定。比如下面的代码:
struct person
{
	int _id;
    string _name;
};
int main()
{
	person p = { 21314341,"张三"};
	int arr[] = { 1,2,3,4 };

	return 0;
}
  • C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。例如下面的代码:
struct person
{
	int _id;
	string _name;
};
int main()
{
	//int _a = 1;
	int _a{ 1 };  //用1初始化_a变量
	double _d{ 1.0 };

	person s{ 12345,"李四" };
	int arr[]{ 1,2,3,4 };

	return 0;
}
  • C++11中列表初始化也可以适用于new表达式中
int main()
{
	int* p = new int[4] {1, 2, 3, 4};

	return 0;
}
  • 创建对象时也可以使用列表初始化方式调用构造函数初始化
struct Date
{
	Date(int year,int month,int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//C++98支持的调用构造函数初始化
	Date d1(2024, 4, 6);

	//C++11,这里也会调用构造函数
	Date d{ 2024,4,6 };
	Date d ={ 2024,4,6 };

	map<string, string> m{ {"string","字符串"},{"world","世界"} };
	set<int> s{ 1,2,5,3 };

	return 0;
}

二.std::initializer_list

initializer_list 文档:链接: link

int main()
{
	auto il = { 10, 20, 30 }; 
	cout << typeid(il).name() << endl;

	//运行结果:class std::initializer_list<int>
	return 0;
}
int main()
{
	auto il1 = { 10, 20, 30 };
	initializer_list<int> il2 = { 10,20,30 };
	cout << sizeof(il1) << endl;
	cout << sizeof(il2) << endl;
	
	//运行结果
	// 8
	// 8
	return 0;
}

根据文档以及上面的代码可以理解为:
initializer_list 类似于一个容器,但是它不存储数据,{10,20,30}这个数组被放到了常量区,然后initializer_list里面有两个指针,一个指向数组起始位置,一个指向数组的最后。
代码调试验证:
在这里插入图片描述
initializer_list有相关接口:
以代码的形式讲解:

int main()
{
	auto il1 = { 10, 20, 30 };
	initializer_list<int> il2 = { 10,20,30 };

	cout << &il2 << endl;
	cout << il2.begin() << endl;   //返回指向的数组的第一个元素的指针
	cout << il2.end() << endl;     //返回指向的数组的最后一个元素的下一个元素的指针
	cout << il2.size() << endl;     //求指向的数组的大小
	
	//运行结果:
	//0053FBC4  
	//0053FBB0
	//0053FBBC
	//3
	return 0;
}

从上面的运行结果来看, il2.begin() 返回的地址是被指向数组的起始位置,( {10,20,30}是才能放在常量区的,取不到地址的,这里取的地址是被拷贝到栈上的数组的地址)
std::initializer_list使用场景:

std::initializer_list一般是作为构造函数参数,C++11对STL中的不少容器就增加std::initializer_list作为参数的构造函数(如下图),例如vector,map,list,set等这样初始化容器对象就更方便了。也可以作为operator=的参数,这样就可以用大括号赋值。
在这里插入图片描述
在这里插入图片描述

例如以下代码:

int main()
{
	vector<int> v{ 1,2,3,4,5 };   //大括号进行初始化
	v = { 8,13,1 };               //大括号赋值

	//下面详解这一个怎么初始化的
	map<string, string> dict = {{"string", "字符串"}};

	return 0;
}
//下面详解详解{"string", "字符串"}怎么初始化dict的
	map<string, string> dict = {{"string", "字符串"}};

	//{"string", "字符串"}-->pair<const char*,const char*>
	//但是map里面存储的键值对类型为pair<const key,T>
	//那么pair<const char*, const char* >是怎么转换为pair<const key,T>的呢?
	//这里是借助的pair的一个拷贝构造,pair的拷贝构造利用了模板
	//pair的拷贝构造:template<class U, class V> 
	//              pair (constpair<U,V>& pr);
	//先利用pair的拷贝构造将pair<const char*, const char* >转换为pair<const string,string>
	//然后再利用initializer_list 去构造初始化dict

三.声明

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

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

例子:

int main()
{
	int _a = 10;
	auto p = &_a;
	cout << typeid(p).name() << endl;  
	//运行结果:
	//int *

	map<string, int> mapcount;
	string arr[] = { "apple","string","right","left","apple","right","right","left" };
	for (auto& e : arr)   //自动识别e的类型为pair<string,int>
	{
		mapcount[e]++;
	}

	//map<string, int>::iterator it = mapcount.begin();
	auto it = mapcount.begin();     
	while (it != mapcount.end())
	{
		cout << it->first << ":" << it->second << endl;
		++it;
	}

	return 0;
}

注意:不建议用auto去做返回值,因为有弊端,例如下面这种场景:

auto func()
{
	int ret = 10;

	return ret;
}
auto func2()
{
	auto ret = func();

	return ret;
}

auto func3()
{
	auto ret = func2();

	return ret;
}
auto func1()
{
	auto ret = func3();

	return ret;
}
/当我们想要知道func1中ret的类型时,还要去看func3的返回值,func3的返回值也是auto,又得去看func2的,如果一个项里面函数特别多时,则就会很麻烦。

四.decltype关键字

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

举个例子:

int main()
{
	int _a = 10;
	decltype(_a) y;    //用 _a 声明的类型为 y 的类型
	cout << typeid(y).name() << endl;
	//运行结果
	//  int

	return 0;
}

使用场景:需要定义一个变量(对象等),但是需要根据另一个变量或则对象的类型来定义时,可以使用关键字decltype。
例如:

template<class T1,class T2>
void func(const T1 x, const T2 y)
{
	decltype(x * y) ret;
	ret = x * y;

	cout << ret << endl;
}

五.nullptr

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

六.新增加容器—静态数组array、forward_list以及unordered系列

如图:圈出来的四个容器为新增
在这里插入图片描述

6.1unordered_map与unoredered_set

unordered_map与unoredered_set的使用与相关接口以及模拟实现在上篇文章已经讲过,这里就不做详解(文章链接link)

6.2array

array文档链接link

在这里插入图片描述

array是一个静态数组,大小为N,数据存储类型为T。
array的相关接口:

函数名作用
size返回数组中元素的个数
empty判断是否为空
front返回第一个元素
[ ]下标随机访问
back返回最后一个元素
data返回指向第一个元素的指针
at(size_t i)返回数组中下标为i的元素的引用

演示代码:

C++11 array(静态数组)
int main()
{
	array<int, 10> arr;
	vector<int> v = { 1,2,3,4,5,6,7,8,9 };
	for (size_t i = 0; i < v.size(); i++)
	{
		arr.at(i) = v[i];
	}
	for (auto e : arr)
	{
		cout << e << " ";
	}
	cout << endl;
	cout << arr.size() << endl;
	cout << arr.back() << endl;
	cout << arr.front() << endl;

	int* p = arr.data();
	cout << *p << endl;

//运行结果:
1 2 3 4 5 6 7 8 9 -858993460
10
-858993460
1
1
	return 0;
}

当数组没有初始化完时,剩余的没有被处理,为随机值。
array所支持的接口,vector基本上都能支持,并且vector容器使用比array更方便,接口也更多,所以容器array的出现,感觉多此一举。

6.3 forward_list(单链表)

forward_list 文档链接link

文档总结:forward_list是一个单链表,节点里面只有一个指向下一个节点的指针和一个存储数据的变量,因为它不方便找前一个,所以不支持当前位置插入与删除,只支持在当前位置的下一个节点后面插入,删除当前位置的下一个节点,但是支持头插头删(效率高),不支持尾删(因为要遍历找尾,效率低)。

代码演示:

//forward_list(单链表)
int main()
{
	forward_list<int> flist;
	flist.push_front(1);
	flist.push_front(3);   //头插
	flist.push_front(2);
	for (auto e : flist)
	{
		cout << e << " ";
	}
	cout << endl;
	flist.insert_after(flist.begin(), 1000);   //在第一个位置的后面插入1000
	flist.insert_after(flist.begin(),100);     //在第一个位置的后面插入100
	flist.erase_after(flist.begin());     //删除第一个位置的后面的一个元素100
	flist.sort();              //排序接口
	for (auto e : flist)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}
//运行结果:
2 3 1
1 2 3 1000

🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵🐵
本章节完~ 后续的关于C++11的新特性在下篇

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

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

相关文章

Leetcode算法训练日记 | day18

一、找树左下角的值 1.题目 Leetcode&#xff1a;第 513 题 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出:…

nandgame中的Memory(内存操作):栈、堆、静态区

Push Memory Push Memory 将内存中的值push到栈内堆栈顶部的值是一个内存地址。从堆栈中弹出地址。获取内存地址的当前内容&#xff0c;并将其推送到堆栈上。POP_A //堆栈顶部的值是一个内存地址。从堆栈中弹出地址。 D *A //获取内存地址的当前内容 PUSH_D //将其推送到…

JVM性能调优——运行时参数

文章目录 1、JVM参数选项类型1.1、标准参数选项1.2、非标准参数选项1.3、非稳定参数选项 2、添加JVM参数的方式3、常用JVM参数选项4、通过Java代码获取JVM参数5、小结 熟悉JVM参数对于系统调优是非常重要的。比如一个高流量的延迟的电子交易平台&#xff0c;它要求的响应时间都…

ROS机器人未知环境自主探索功能包explore_lite最全源码详细解析(五)

本系列文章主要针对ROS机器人常使用的未知环境自主探索功能包explore_lite展开全源码的详细解析&#xff0c;并进行概括总结。 本系列文章共包含六篇文章&#xff0c;前五篇文章主要介绍explore_lite功能包中 explore.cpp、costmap_tools.h、frontier_search.cpp、costmap_clie…

MySQL:关于数据库的一些练习题

文章目录 前面的内容已经把数据库的一些必要知识已经储备好了&#xff0c;因此下面就对于这些语句进行一些练习&#xff1a; 批量插入数据 insert into actor values (1, PENELOPE, GUINESS, 2006-02-15 12:34:33), (2, NICK, WAHLBERG, 2006-02-15 12:34:33);SQL202 找出所有…

C/S医学检验LIS实验室信息管理系统源码 医院LIS源码

LIS系统即实验室信息管理系统。LIS系统能实现临床检验信息化&#xff0c;检验科信息管理自动化。其主要功能是将检验科的实验仪器传出的检验数据经数据分析后&#xff0c;自动生成打印报告&#xff0c;通过网络存储在数据库中&#xff0c;使医生能够通过医生工作站方便、及时地…

一起学习python——基础篇(14)

今天讲一下python的json解析方式。 上一篇文章讲述了将传参数据转换为json格式的数据传给后台&#xff0c;如果后端返回的json格式数据&#xff0c;我们该如何解析呢&#xff1f; 例子一&#xff1a;简单的json数据格式 如果后端返回的json数据如下&#xff0c; { "na…

【leetcode面试经典150题】34.有效的数独(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

Docker Compose 一键安装

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

【C++学习】C++11新特性(第二节)—— 右值引用与移动语义超详解

文章目录 文章简介二.右值引用1.什么是左值&#xff0c;什么是右值&#xff1f;什么是左值引用&#xff0c;什么是右值引用&#xff1f;2.左值引用与右值引用比较 三.右值引用使用场景和意义1.左值引用的使用场景&#xff1a;2.左值引用的短板&#xff1a;3.右值引用与移动构造…

2024大模型落地应用案例集(免费下载)

【1】扫码关注本公众号 【2】私信发送 2024大模型落地应用案例集 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。

【Linux】环境下OpenSSH升级到 OpenSSH_9.6P1(图文教程)

漏洞描述 OpenSSH&#xff08;OpenBSD Secure Shell&#xff09;是加拿大OpenBSD计划组的一套用于安全访问远程计算机的连接工具。该工具是SSH协议的开源实现&#xff0c;支持对所有的传输进行加密&#xff0c;可有效阻止窃听、连接劫持以及其他网络级的攻击。OpenSSH 9.6之前…

深入浅出Golang image库:编写高效的图像处理代码

深入浅出Golang image库&#xff1a;编写高效的图像处理代码 引言image库概览图像处理基础概念image库的主要组成和功能image接口图像格式的支持color模型 结论 图像的基本操作创建图像新图像的创建从文件加载图像 图像的保存与导出图像的颜色和像素处理绘制基本形状和文字 高级…

无网络连接 请检查你的网络设置 然后重试 [2604] 彻底解决方案

错误提示&#xff1a;无网络连接 请检查你的网络设置 然后重试 [2604] 彻底解决方案如下&#xff1a; 方案一&#xff1a; 打开Internet Explorer浏览器&#xff0c;选择"工具 > Internet 选项"。 在Internet属性窗口下&#xff0c;点击高级下滑到安全模块分类…

[漏洞复现]D-Link未授权RCE漏洞复现(CVE-2024-3273)

声明&#xff1a;亲爱的读者&#xff0c;我们诚挚地提醒您&#xff0c;Aniya网络安全的技术文章仅供个人研究学习参考。任何因传播或利用本实验室提供的信息而造成的直接或间接后果及损失&#xff0c;均由使用者自行承担责任。Aniya网络安全及作者对此概不负责。如有侵权&#…

Linux查看系统配置信息的命令【lscpu】【free】【df】【uname】【lsblk】【top】

目录 1.查看CPU信息【lscpu】 2.查看内存信息【free】 3.查看文件系统信息【df】 4.查看系统信息【uname】 知识扩展&#xff1a;Red Hat Enterprise Linux 和 Debian GNU/Linux 两者的发展介绍 知识扩展&#xff1a;Centos 和 ubuntu的区别 知识扩展&#xff1a;更多 …

Quanto: PyTorch 量化工具包

量化技术通过用低精度数据类型 (如 8 位整型 (int8)) 来表示深度学习模型的权重和激活&#xff0c;以减少传统深度学习模型使用 32 位浮点 (float32) 表示权重和激活所带来的计算和内存开销。 减少位宽意味着模型的内存占用更低&#xff0c;这对在消费设备上部署大语言模型至关…

Python学习从0开始——项目一day01爬虫

Python学习从0开始——项目一day01爬虫 一、导入代码二、使用的核心库三、功能测试3.1初始代码3.2新建文件3.3代码调试 四、页面元素解析4.1网页4.2修改代码4.3子页面4.4修改代码 一、导入代码 在Inscode新建一个python类型的项目&#xff0c;然后打开终端&#xff0c;粘贴以下…

高中数学:三角函数-基础知识

一、任意角 顺时针旋转是负值角 逆时针旋转式正值角 一个角对应一个终边 一个终边对应无数个角 xk*360 例题 二、弧度制 弧长与半径的比值&#xff0c;就是角度 常见角度与弧度的对应关系 例题 三、弧长与扇形面积公式 注意&#xff1a;弧度制下的扇形面积公式&#x…

SpringBoot --pagehelper分页

目录 1.建立数据库 2.页面显示 3.基本逻辑 4.配置依赖 5.使用pagehelper 6.页面列表 页面 效果 1.建立数据库 create database if not exists my_book; use my_book; create table if not exists myBook (id int primary key auto_increment,name varchar(50) not …