二十、C++11(上)

news2024/10/7 16:16:28

文章目录

  • 一、前言
  • 二、C++11诞生简介
  • 三、列表初始化
    • (一){}初始化
    • (二)initializer_list容器
      • 1. initializer_list 概念
      • 2. initializer_list的使用场景
      • 3. initializer_list接口函数模拟实现
  • 四、关键字
    • (一)auto
    • (二)decltype
    • (三)nullptr
  • 五、范围for
  • 六、STL的更新
    • (一)新容器
      • 1. array容器
      • 2.forward_list容器
      • 3.unordered_map和unordered_set容器
    • (二)新方法
    • (三)新函数
      • 1.to_string

一、前言

经过了漫长了C++语法学习还有高阶数据结构学习
差不多来到了C++学习的收尾部分C++11
这部分主要是一些零碎的知识点
中间还可能涉及到一些linux相关知识

二、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的小故事。

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。

三、列表初始化

(一){}初始化

我们在前面的C语言中我们一般习惯使用这样子的代码来初始化数组。

int arr[] = { 1,2,3,4,5 };
int arr2[4] = { 0 };

在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。

int arr[] = { 1,2,3,4,5 };
point p{ 1,2};

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

// 对于内置类型进行初始化
int a = { 3 };
int a{ 3 };

// 对于数组进行初始化
int arr[5] = { 1,2,3,4,5 };
int arr2[5]{ 1,2,3,4,5 };

// 对于结构体元素进行初始化
point  p = { 1,3 };
point  p{ 1,3 };

// new表达式
int* p1 = new int[4] {0};
// int* p1 = new int[4] = {0};
// new表达式初始化的时候不可以加等号

这里特别要注意的一点是,使用new表达式初始化不能使用等于号了。

创建自定义对象的时候也可以使用列表初始化。

class Date
{
public:
	Date(int year,int month , int day)
		:_year(year)
		,_month(month)
		,_day(day)
	{
		;
	}
private:
	int _year;
	int _month;
	int _day;
};

void test4()
{
	Date d1 = { 2023,1,23 };
	Date d2{ 2023,1,23 };
}

(二)initializer_list容器

1. initializer_list 概念

C++11中新增了initializer_list容器。
C++11中能够使用{}初始化就是因为这个容器的功劳。
在这里插入图片描述

  • begin和end迭代器 用于支持迭代器遍历
  • size函数支持获取容器中的元素个数

它的本质就是一个用大括号括起来的列表
我们可以使用这样子的代码来确认它的类型

auto l = { 1,2,3,4,5 };
cout << typeid(l).name() << endl;

2. initializer_list的使用场景

initializer_list容器并没有提供增删查改相关接口函数,这是因为这个容器提供出来了并不是让你储存数据,而是为了能够让其他容器进行列表初始化的。

vector<int> v = { 1,2,3,4,5 };
set<int> s = { 1,2,3,4,5 };
map<int, int> m = { make_pair(1,2),make_pair(3,4) };

这些容器之所以能够支持这样子的列表初始化,实际上是因为容器的成员函数当中增加了一个以initializer_list为参数的构造函数。
在这里插入图片描述
那么底层原理实际上就是,先通过initializer_list构造出来一个列表,然后将这个列表中的所有元素拷贝到我们要构造的容器当中。

3. initializer_list接口函数模拟实现

这里总结下:

  • 构造函数中遍历initializer_list时,可以使用范围for遍历,也是使用迭代器遍历,二者本质上没有差别,因为范围for遍历的底层就是使用迭代器实现的。
  • 假如我们使用迭代器遍历,由于使用了模板参数,所以我们在声明类型的时候要加上typename 告知编译器这是一个类型。
  • 如果不增加一个以initializer_list为参数的赋值运算符重载函数,括号初始化也可以运行。

四、关键字

(一)auto

在C++11中 auto关键字的作用是自动推导类型。

map<int, string> m;
map<int, string>::iterator it = m.begin();
auto it = m.begin();

我们可以发现,使用auto关键字之后代码变得简洁了很多。

在某些情况下,使用auto自动推导类型是十分有用的,比如说下面的情况。

	short a = 32670;
	short b = 32670;
	short c = a + b;
	cout << c << endl;

但是如果我们使用auto推导的话情况就会不一样了。

	short a = 32670;
	short b = 32670;
	auto c = a + b;
	cout << c << endl;

(二)decltype

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

	const int x = 1;
	double y = 2.2;
	
	decltype(x * y) ret;
	decltype (&x) p;
	cout << typeid(ret).name() << endl;
	cout << typeid(p).name() << endl;
	F(1, 'a');
	F(1, 2.2);

在这里插入图片描述

decltype除了能够推演表达式的类型,它还能够推演返回值的类型

void* GetMemory(size_t size)
{
	return malloc(size);
}
void test11()
{
	cout << typeid(decltype(GetMemory)).name() << endl;
	cout << typeid(decltype(GetMemory(0))).name() << endl;
}

在这里插入图片描述

  • 如果我们不带参数,则推导的是函数的类型
  • 如果我们带参数,则推导的是返回值的类型

(三)nullptr

在C语言中NULL 即空指针,被定义成了0,但是这在一些情况下可能会带来一些问题。

比如说下面的代码。

void f(int arg)
{
	cout << "void f(int arg)" << endl;
}
void f(int* arg)
{
	cout << "void f(int* arg)" << endl;
}
int main()
{
	f(NULL);    
	return 0;
}

当我们像函数参数中传递一个空指针的时候实际上我们是想要调用第二个函数,可是结果缺不符合我们的预期。
在这里插入图片描述
于是C++11的标准中引入了nullptr来代表空指针,使得我们写的代码更加的严谨!

void f(int arg)
{
	cout << "void f(int arg)" << endl;
}
void f(int* arg)
{
	cout << "void f(int* arg)" << endl;
}
int main()
{
	f(nullptr);    
	return 0;
}

五、范围for

这个语法我们从刚刚学习C++就开始使用了,语法格式如下。

	vector<int> v;
	v.push_back(2);
	v.push_back(5);
	v.push_back(4);
	v.push_back(7);
	v.push_back(1);

	for (auto x : v)
	{
		cout << x << endl;
	}

主体是这四行代码。

	for (auto x : v)
	{
		cout << x << endl;
	}
  • auto关键字的目的是为了自动推导类型,当然如果你知晓类型是什么格式也可以直接声明之来替换auto
  • x为变量名,它代表的是容器中的每个数据,你也可以修改它的名字使之更好理解
  • 变量名和容器名之间要用分号隔开
  • 最后的就是容器名字,输入你想要遍历的容器即可
    范围for的底层原理并不复杂,其实就是迭代器遍历,只要一个容器可以被迭代器遍历,那么它就可以被范围for遍历!

和普通for循环类似 范围for也可以被continue和break关键字打断

范围for的两个使用条件

  • 它的范围要是确定的 在begin和end迭代器之间
  • 它的迭代器要支持++和==操作,如果它的迭代器不支持此操作,那么范围for也是不支持的。

六、STL的更新

(一)新容器

1. array容器

它的本质是一个静态数组

我们创建一个array对象需要提供两个参数
一个是数据的类型 ,一个是大小,具体示例代码如下

    array<int,10> a1;
	array<double, 12> a2;

array和普通数组的对比:
相同点:

  • 它和普通数组一样支持通过下标访问操作符【】来访问数据
  • 支持范围for遍历
  • 创建后的数组大小不可改变。

不同点:

  • 它使用一个类对于array容器进行了封装,对于数组边界的检查更加严格了,如果使用下标访问操作符越界会出现断言检查,如果使用 at 成员函数访问会抛出异常
  • 普通数组对于越界的检查只有在写操作的时候才会很严格,如果只是进行读操作并不会那么严格。

因为它的对象是在栈上创建的,而栈的空间一般都很小,所以说我们不宜使用array创建过大的对象。

2.forward_list容器

forward_list容器的本质上是一个单链表!

相比于双链表来说单链表的缺点太多了,所以说我们平时不常使用forward_list容器来存储数据。

这里简单介绍下forward_list容器的几个特点:

  • forward_list容器只支持头插头删 因为单链表的尾插尾删,都要先找到尾,时间复杂度是O(N) 而头插头删的时间复杂度则是O(1)。
  • forward_list容器只支持头插头删,因为单链表的尾插尾删,都要先找到尾,时间复杂度是O(N) 而头插头删的时间复杂度则是O(1)。
  • forward_list容器只支持头插头删 因为单链表的尾插尾删,都要先找到尾,时间复杂度是O(N) 而头插头删的时间复杂度则是O(1)。

3.unordered_map和unordered_set容器

关于这两个容器,它们的底层是用哈希表实现的,具体的使用可以参考我之前的博客!

(二)新方法

C++容器中提供了一些新方法

  • 提供了一个以initializer_list作为参数的构造函数,用于支持列表初始化。
  • 提供了cbegin和cend方法,用于返回const迭代器。
  • 提供了emplace系列方法,并在容器原有插入方法的基础上重载了一个右值引用版本的插入函数,用于提高向容器中插入元素的效率。

(三)新函数

1.to_string

在C++11中提供了一个函数可以将别的类型转化为字符串类型!

to_string()

它的底层实现原理是函数重载!

在这里插入图片描述
string类型转化为其他类型!
如果要将string类型转化为其他类型 这里我们只需要调用对应的函数即可
在这里插入图片描述
最后的数字代表转化后的类型:

i 代表 int
l 代表 long
ll 代表 long long 依次类推

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

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

相关文章

duilib中使用mfc控件

我在界面相隔挺远的位置添加2个mfc控件&#xff0c; 需要添加&#xff1a; 1. 添加 CMfcWndUI 类&#xff0c;这是为了调用mfc控件用的 2. 添加 duilib界面 CDuiFrameWnd 3.重写 2中界面的virtual CControlUI* CreateControl(LPCTSTR pstrClassName); 函数 需要注意的地方…

xray工具—代理扫描、爬虫扫描、Burp联动

xray工具—代理扫描、爬虫扫描、Burp联动 1. Xray介绍1.1. 支持漏洞检测类型1.2. 官网地址 2. 常用扫描模式2.1. 生成证书2.1.1. 浏览器安装证书 2.2. Xray基础主动扫描2.2.1. 基础主动扫描命令2.2.2. 基础主动扫描结果 2.3. Xray代理模式扫描2.3.1. 代理模式配置代理2.3.2. 代…

一场变革来到零售业,盖雅「劳动力账户」助力连锁门店全面管理人效

‍ 上半年&#xff0c;逐渐回暖的出游&#xff0c;为文旅和线下零售业的营收创造了希望&#xff0c; 但面对高周转率和低利润率的行业竞争格局&#xff0c;比起令人兴奋的营收&#xff0c;大部分零售企业仍在焦虑营收背后的成本。 或许是过去三年的环境让更多企业学会了「精…

Microsoft Build 两大主题:Copilots 和插件

在 Microsoft Build 中&#xff0c;贯穿会议的两个主要主题是 Copilots - 涵盖广泛产品和服务的 AI 助手 - 以及插件&#xff0c;它们有效地将 Copilots 转变为聚合器&#xff0c;可能使其成为企业和消费者客户的一站式商店。 微软MVP实验室研究员 张善友 深圳友浩达 CTO&…

Python:Python编程:金融量化交易

金融量化交易 1. numpy2. scipy3. Pandas3.1 : Series 3.2&#xff1a; DataFrame代码示例 在金融量化交易中&#xff0c;下面几个模块是应用的比较广泛的 numpy (Numberic Python) : 提供大量的数值编程工具&#xff0c;可以方便的处理&#xff1a;向量矩阵等运算&#xff0c;…

cuda编程学习——CUDA内存介绍(七)

前言 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 CUDA编程&#xff1a;基础与实践 樊哲勇 文章所有代码可在我的GitHub获得&#xff0c;后续会慢慢更新 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 …

Linux 中断子系统中GIC 中断控制器基本分析

GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器&#xff0c;类似 Cortex-M 内核&#xff08;STM32&#xff09;中的 NVIC。 GIC&#xff1a;Generic Interrupt Controller&#xff0c;通用中断控制器。 NVIC&#xff1a;Nested Vectored Interrupt Controller&#…

RTX4060Ti上演史诗级尴尬,线下核心商区斩获个位数销量

时隔两年半&#xff0c;一代甜品 RTX 3060 Ti 显卡继任者 RTX 4060 Ti 终于上架了。 经过几天网上对比测试&#xff0c;情况就这么个情况&#xff0c;综合性能提升堪堪 10% 左右&#xff0c;价格上涨至 3199 元起。 来源&#xff1a;clubic 参考 RTX 4090 超 50% 性能提升&am…

聊聊 220V交流 过零检测

聊聊过零检测&#xff0c;以及如何实现过零检测 ...... by 矜辰所致目录 前言一、什么是过零检测1.1 为何需要过零检测 二、如何做过零检测2.1 光耦2.2 比较器/运放2.3 三极管/MOS管2.4 过零检测芯片 三、过零检测电路结语 前言 最近正好项目需求遇到需要做过零检测&#xff…

【刷题之路Ⅱ】LeetCode 1823. 找出游戏的获胜者(约瑟夫问题)

【刷题之路Ⅱ】LeetCode 1823. 找出游戏的获胜者 一、题目描述二、解题1、方法1——单向环形链表1.1、思路分析1.2、代码实现 2、方法2——队列2.1、思路分析2.2、先将队列实现一下2.3、代码实现 一、题目描述 原题连接&#xff1a; 1823. 找出游戏的获胜者 题目描述&#xff…

Java基础篇 | Java基础语法

✅作者简介&#xff1a;大家好&#xff0c;我是Cisyam&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Cisyam-Shark的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色…

2023年上半年网络工程师上午真题及答案解析

1.固态硬盘的存储介质是( )。 A.光盘 B.闪存 C.软盘 D.磁盘 2.虚拟存储技术把( )有机地结合起来使用&#xff0c;从而得到一个更大容量的“内存”。 A.内存与外存 B.Cache与内存 C.寄存器与Cache D.Cache与外存 3.下列接口协议中&…

论文阅读 —— 语义激光SLAM

文章目录 点云语义分割算法1 基于点的方法2 基于网格的方法3 基于投影的方法 一、SLOAM1.1 语义部分1.2 SLAM部分1.2.1 树的残差1.2.2 地面的残差1.2.3匹配过程 二、SSC: Semantic Scan Context for Large-Scale Place Recognition2.1 两步全局语义ICP2.1.1 快速偏航角计算2.1.…

【已解决---ChatGPT学术优化下载安装问题集锦】

文章目录 问题1&#xff1a;关于配置完项目后关闭&#xff0c;如何再次打开快速启动。问题2&#xff1a;项目链接打不开,是404。问题3&#xff1a;出现关于API的报错。问题4&#xff1a;[Local Message] Request timeout. Network error. Please check proxy settings in confi…

8.Ansible Variables介绍

什么是Ansible Variables&#xff1f; 就像任何其他脚本或编程语言一样&#xff0c;变量用于存储变化的值&#xff61;例如, 假设我们要尝试执行相同的操作, 将修补程序应用于数百台服务器&#xff61;我们只需要一个playbook就可以满足所有100台服务器的需求&#xff61;但是,…

chatgpt赋能python:Python中提取指定元素——一个简单而精细的方法

Python中提取指定元素——一个简单而精细的方法 在网页抓取中&#xff0c;经常需要提取特定元素&#xff0c;例如标题、段落、图片等&#xff0c;以便于后续的数据处理与分析。而Python则是许多工程师在此领域中的首选语言&#xff0c;其灵活的语法和强大的第三方库给爬虫和数…

idea怎么搭建springboot

一般来说&#xff0c;用IDEA创建SpringBoot项目有两种方式。其一是Spring官网提供了一个快速生成SpringBoot项目的网站&#xff0c;可以在官网直接下载后&#xff0c;再导入IDEA中。另外一种是直接用IDEA创建一个SpringBoot项目&#xff0c;一般开发也是用的这种方式进行创建。…

为什么串行接口速率比并行接口快?

串行接口的速率会比并行快&#xff0c;可以从下面四个方面考虑&#xff1a; ①高速串口不需要时钟信号来同步数据流&#xff0c;也就没有时钟周期性的边沿&#xff0c;频谱不会集中&#xff0c;所以噪声干扰少很多。 以PCIE和SATA为例&#xff0c;时钟信息通过8b/10b编码已经集…

正运动技术运动控制器如何快速实现单轴/多轴同步跟随功能?

本文主要介绍如何使用MOVESYNC指令快速实现单轴/多轴同步跟随功能&#xff0c;适用于XYZ&#xff08;R&#xff09;、SCARA、DELTA等常见机械结构&#xff0c;在流水线点胶、流水线产品分拣、流水线产品搬运等场景中广泛应用。 阅读本文&#xff0c;学习同步跟随的原理和实现方…

抖音seo源码系统开发服务商选择

“账号矩阵”是一种账号运营的高阶玩法&#xff0c;指一个运营主体同时开设多个平台多个账号利用品牌联动的形式来实现账号之间的相关引流&#xff0c;以账号组的形式实现企业营销价值最大化。那么运营多个账号&#xff0c;短视频平台内容是核心&#xff0c;势必要招募多个剪辑…