【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.hqwc.cn/news/617085.html

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

相关文章

【静态分析】静态分析笔记04 - 数据流分析(理论)

参考&#xff1a; 【课程笔记】南大软件分析课程4——数据流分析基础&#xff08;课时5/6&#xff09; - 简书 --------------------------------------------------------------------------- 1. 迭代算法 本质&#xff1a;常见的数据流迭代算法&#xff0c;目的是通过迭代…

pycharm debug 的时候 waiting for process detach

当你使用pycharm debug或者run的时候&#xff0c;突然出现了点不动&#xff0c;然后一直显示&#xff1a;waiting for process detach 可能是以下问题&#xff1a; 1、需要设置Gevent compatible pycharm一直没显示运行步骤&#xff0c;只是出现waiting for process detach-C…

C++11 数据结构2 线性表的链式存储,实现,测试

线性表的链式存储 --单链表 前面我们写的线性表的顺序存储(动态数组)的案例&#xff0c;最大的缺点是插入和删除时需要移动大量元素&#xff0c;这显然需要耗费时间&#xff0c;能不能想办法解决呢&#xff1f;链表。 链表为了表示每个数据元素与其直接后继元素之间的逻辑关系…

Linux系统——Elasticsearch企业级日志分析系统

目录 前言 一、ELK概述 1.ELK简介 2.ELK特点 3.为什么要使用ELK 4.完整日志系统基本特征 5.ELK工作原理 6.Elasticsearch介绍 6.1Elasticsearch概述 6.2Elasticsearch核心概念 7.Logstash介绍 7.1Logstash简介 7.2Logstash主要组件 8.Kibana介绍 8.1Kibana简介 …

Netty学习——高级篇2 Netty解码技术

接上篇&#xff1a;Netty学习——高级篇1 拆包 、粘包与编解码技术&#xff0c;本章继续介绍Netty的其他解码器 1 DelimiterBasedFrameDecoder分隔符解码器 DelimiterBasedFrameDecoder 分隔符解码器是按照指定分隔符进行解码的解码器&#xff0c;通过分隔符可以将二进制流拆分…

C语言基础(四)

C语言基础 一维数组数组初始化全部初始化部分初始化数组的默认值冒泡排序 字符数组 二维数组初始化行数是否可省略列数是否可以省略部分初始化 访问二维字符数组 函数分类库函数自定义函数调用自定义函数函数声明 一维数组 概念&#xff1a;一组数据类型相同的元素的集合 <…

家庭网络防御系统搭建-虚拟机安装siem/securityonion网络连接问题汇总

由于我是在虚拟机中安装的security onion&#xff0c;在此过程中&#xff0c;遇到很多的网络访问不通的问题&#xff0c;通过该文章把网络连接问题做一下梳理。如果直接把securityonion 安装在物理机上&#xff0c;网络问题则会少很多。 NAT无法访问虚拟机 security onion虚拟…

Mapmost Alpha:开启三维城市场景创作新纪元

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【详细教程】MySQL 高可用架构代码实现

前言 对于 MySQL 数据库作为各个业务系统的存储介质&#xff0c;在系统中承担着非常重要的职责&#xff0c;如果数据库崩了&#xff0c;那么对于读和写数据库的操作都会受到影响。如果不能迅速恢复&#xff0c;对业务的影响是非常大的。之前 B 站不是出过一次事故么&#xff0…

网络篇05 | 应用层 http/https

网络篇05 | 应用层 http/https 01 HTTP请求报文协议&#xff08;Request&#xff09;1&#xff09;Request简述2&#xff09;请求行&#xff08;首行&#xff09;3&#xff09;请求头&#xff08;Request Headers&#xff09;4&#xff09;空行5&#xff09;正文&#xff08;Re…

每日一题(leetcode238):除自身以外数组的乘积--前缀和

不进阶是创建两个数组&#xff1a; class Solution { public:vector<int> productExceptSelf(vector<int>& nums) {int nnums.size();vector<int> left(n);vector<int> right(n);int mul1;for(int i0;i<n;i){mul*nums[i];left[i]mul;}mul1;for…

【论文速读】| 基于大语言模型的模糊测试技术

本次分享论文为&#xff1a;Large Language Models Based Fuzzing Techniques: A Survey 基本信息 原文作者&#xff1a;Linghan Huang, Peizhou Zhao, Huaming Chen, Lei Ma 作者单位&#xff1a;悉尼大学&#xff1b;东京大学&#xff1b;阿尔伯塔大学 关键词&#xff1a;…