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

在这里插入图片描述

文章目录

  • 一.文章前言
  • 二.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// 8return 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//3return 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;//运行结果//  intreturn 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
1return 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);   //在第一个位置的后面插入1000flist.insert_after(flist.begin(),100);     //在第一个位置的后面插入100flist.erase_after(flist.begin());     //删除第一个位置的后面的一个元素100flist.sort();              //排序接口for (auto e : flist){cout << e << " ";}cout << endl;return 0;
}
//运行结果:
2 3 1
1 2 3 1000

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

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

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

相关文章

【Altium Designer 20 笔记】隐藏PCB上的信号线(连接线)

使用网络类隐藏特定类型的信号线 如果你想要隐藏特定类型的信号线&#xff08;例如电源类&#xff09;&#xff0c;你可以首先创建一个网络类。使用快捷键DC调出对象类浏览器&#xff0c;在Net Classes中右击添加类&#xff0c;并重命名&#xff08;例如为“Power”&#xff0…

centos编译安装nginx1.24

nginx编译1.24&#xff0c;先下载安装包 机器通外网的话配置nginx的yum源直接yum安装 vim /etc/yum.repos.d/nginx.repo [nginx-stable] namenginx stable repo baseurlhttp://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck1 enabled1 gpgkeyhttps://nginx.org…

fastjson 序列化问题

问题: 使用fastjson 的 对同一个JSONObject对象 多次引用后, 通过 JSON.toJSONString() 方法进行json序列化时出现只有第一次的可以成功序列化未json string 字符串, 后面的对象都为引用地址; 示例: public static void main(String[] args) {JSONObject jsonObject new JSON…

7 个适用于 Windows 的最佳电脑分区数据恢复软件

磁盘分区对于正确存储数据以便从硬盘驱动器快速轻松地访问非常有帮助。但是&#xff0c;如果分区损坏&#xff0c;存储在其中的所有数据都会突然变得无法访问。磁盘分区损坏的原因可能有很多&#xff0c;其中最突出的是病毒攻击、突然断电、物理损坏或由于创建坏扇区。 但是&a…

eNSP-抓包解析TCP三次握手和四次挥手的过程

一、环境搭建 1.设备连接 并 启动所有设备 2.服务器配置 3.客服端配置 二、抓包测试 1.打开抓包软件 2.客户端获取数据 三、抓包结果

深度学习体系结构——CNN, RNN, GAN, Transformers, Encoder-Decoder Architectures算法原理与应用

1. 卷积神经网络 卷积神经网络&#xff08;CNN&#xff09;是一种特别适用于处理具有网格结构的数据&#xff0c;如图像和视频的人工神经网络。可以将其视作一个由多层过滤器构成的系统&#xff0c;这些过滤器能够处理图像并从中提取出有助于进行预测的有意义特征。 设想你手…

Blender3.5 下载地址及安装教程

Blender是一款开源的3D计算机图形软件&#xff0c;广泛应用于动画制作、游戏开发、建模、渲染等领域。它提供了一套强大的工具和功能&#xff0c;让用户能够进行三维建模、动画制作和视觉效果的创作。 Blender支持多种文件格式的导入和导出&#xff0c;使用户能够与其他软件进…

[MAUI]集成富文本编辑器Editor.js至.NET MAUI Blazor项目

文章目录 获取资源从源码构建从CDN获取获取扩展插件 创建项目创建控件创建Blazor组件初始化保存销毁编写渲染逻辑 实现只读/编辑功能切换模式获取只读模式状态响应切换事件 实现明/暗主题切换项目地址 Editor.js 是一个基于 Web 的所见即所得富文本编辑器&#xff0c;它由CodeX…

红豆Cat 1开源|项目三: 从0-1设计一款HTTP版本RTU(支持GNSS)产品的软硬件全过程

HTTP版RTU&#xff08;支持GNSS&#xff09;项目概述 RTU&#xff08;Remote Terminal Unit&#xff09;&#xff0c;中文即远程终端控制系统&#xff0c;负责对现场信号、工业设备的监测和控制。RTU是构成企业综合自动化系统的核心装置&#xff0c;通常由信号输入/出模块、微…

RT-Thread内核简介

1、RT-Thread 内核介绍 RT-Thread 内核架构图,内核处于硬件层之上,内 核部分包括内核库、实时内核实现 内核库是为了保证内核能够独立运行的一套小型的类似 C 库的函数实现子集。这部分根据编译器的不 同自带 C 库的情况也会有些不同,当使用 GNU GCC 编译器时,会携带…

全国各省环境规制强度数据(2004-2022年)

01、数据简介 以保护环境为目的&#xff0c;对各种环境污染行为进行规制&#xff0c;政府相关政策规制&#xff0c;是社会性规制的重要内容&#xff0c;包含大气、水、废弃物、噪声污染等外部行为&#xff0c;对这些行为进行规制就是要将整个社会为其承担的成本转化为其自身承…

通过一篇文章让你了解Linux的重要性

Linux 前言一、什么是Linux后台vs前台为何大多数公司选择使用Linux作为后台服务器 二、国内企业后台和用户使用Linux现状IT服务器Linux系统应用领域嵌入式Linux系统应用领域个人桌面应用领域 三、就个人能力提升来说&#xff0c;该如何看待Linux网络上的人都怎么说知乎 腾讯面经…

IDEA Warnings:SQL dialect is not configured.

springboot项目XxxMapper.xml文件打开后显示warnings&#xff1a;SQL dialect is not configured......&#xff08;翻译&#xff1a;未配置SQL语言。&#xff09; 大概意思是没有在IDEA中配置当前sql是MySQl、Oracle还是MariaDB等语言。 配置一下就好&#xff1a; 完了&#…

谈谈我的软考高级考证之路(系统架构设计师篇)

系统架构设计师备考资料请移步 2023年软考高级系统架构设计师视频教程&#xff0c;推荐下载&#xff01;获取。 备考总体策略 • 总体策略&#xff1a;刷视频记笔记刷真题 • 备考时间&#xff1a;建议报完名之后&#xff0c;开始备考&#xff0c;大致2-3个月&#xff08;基础…

【Java多线程】案例(4):定时器

目录 一、定时器是什么? 二、Java标准库中的定时器 三、自己实现定时器 四、标准库中更推荐使用的定时器 一、定时器是什么? 定时器是一种用于在指定时间间隔或特定时间点执行特定任务的工具或设备。在计算机科学中&#xff0c;定时器通常是软件或硬件组件&#xff0c;用…

智过网:注册安全工程师注册有效期与周期解析

在职业领域&#xff0c;各种专业资格认证不仅是对从业者专业能力的认可&#xff0c;也是保障行业安全、规范发展的重要手段。其中&#xff0c;注册安全工程师证书在安全生产领域具有举足轻重的地位。那么&#xff0c;注册安全工程师的注册有效期是多久呢&#xff1f;又是几年一…

Elasticsearch下载安装 以及Reindex(数据迁移)

部署Elasticsearch集群 这里介绍使用的是Elasticsearch 7.6.1的版本&#xff0c;配置两台服务器&#xff0c;一台部署主节点&#xff0c;一台部署两个从节点。 下载地址&#xff1a;https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.16.2-linux-x86_64…

【Java探索之旅】方法重载 递归

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、方法重载1.1 为什么要有方法重载1.2 方法重载的概念与使用1.3 方法签名 二、递归2…

软考高级架构师:随机函数模型

一、AI 讲解 随机函数模型是理解各种随机过程和算法的一个重要概念&#xff0c;在软件工程、算法设计以及系统分析中有着广泛的应用。简而言之&#xff0c;随机函数模型是一种用于描述具有随机性的系统或过程的数学模型&#xff0c;它能够帮助我们预测和分析在不确定性下的系统…

吴恩达2022机器学习专项课程(一) 5.5 特征缩放1 5.6 特征缩放2

问题预览/关键词 什么是特征缩放&#xff1f;作用是什么&#xff1f;特征尺度和参数w权重的关系是&#xff1f;算法为什么要调节w权重&#xff1f;不进行特征缩放对梯度下降的影响&#xff1f;有特征缩放对梯度下降的影响&#xff1f;实现特征缩放的三种方法是&#xff1f;如何…