当前位置: 首页 > news >正文

【C++】学习笔记——C++11_1

文章目录

  • 十九、C++11
    • 1. 统一的列表初始化
      • {}初始化
      • std::initializer_list
    • 2. 声明
      • auto
      • decltype
      • nullptr
    • 4. 范围for
    • 5. STL中的一些变化
      • 新容器
      • 新方法
    • 6. 右值引用和移动语句
      • 左值引用和右值引用
  • 未完待续


十九、C++11

1. 统一的列表初始化

{}初始化

在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。(注意:这里的初始化列表并不是构造函数里的初始化列表。)在C++11中,扩大了用大括号括起的初始化列表的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号 (=),也可不添加。

#include <iostream>
using namespace std;struct Point
{int _x;int _y;
};int main()
{// C++98 就支持的int array1[] = { 1, 2, 3, 4, 5 };int array2[5] = { 0 };Point p = { 1, 2 };// C++11 才支持的int x1 = 1;int x2{ 2 };int array1[]{ 1, 2, 3, 4, 5 };int array2[5]{ 0 };Point p{ 1, 2 };// C++11中列表初始化也可以适用于new表达式中int* pa = new int[4] { 0 };return 0;
}

创建对象时也可以使用列表初始化方式调用构造函数初始化:

#include <iostream>
using namespace std;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(2022, 1, 1);// C++11支持的列表初始化,这里会调用构造函数初始化Date d2{ 2022, 1, 2 };Date d3 = { 2022, 1, 3 };return 0;
}

std::initializer_list

链接戳这里
大部分容器已经引进了 initializer_list ,使得容器也可以通过{}用来初始化。

#include <iostream>
#include <vector>
#include <map>
#include <list>
using namespace std;int main()
{vector<int> v = { 1,2,3,4 };list<int> lt = { 1,2 };// 这里{"sort", "排序"}会先初始化构造一个pair对象map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };// 使用大括号对容器赋值v = { 10, 20, 30 };return 0;
}

2. 声明

auto

c++11提供了多种简化声明的方式,尤其是在使用模板时。auto 的用法是自动类型推导。对于自定义类型,很容易出现类型名字特别长,不方便书写,就可以使用auto来自动推导类型名。

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <map>
#include <list>
using namespace std;int main()
{int i = 10;auto p = &i;auto pf = strcpy;cout << typeid(p).name() << endl << endl;cout << typeid(pf).name() << endl << endl;map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };map<string, string>::iterator it = dict.begin();auto ait = dict.begin();cout << typeid(dict).name() << endl << endl;cout << typeid(it).name() << endl << endl;cout << typeid(ait).name() << endl << endl;return 0;
}

在这里插入图片描述
auto不仅仅可以用作变量类型名,也可以用作函数返回值。

auto func()
{int ret;return ret;
}

decltype

关键字decltype将变量的类型声明为表达式指定的类型。一般在模板情况下,我们不知道接下来要定义的变量是什么类型,我们就可以借助这个关键字,他会推导类型,然后根据这个类型来定义变量。

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>using namespace std;template<class T1, class T2>
void F(T1 t1, T2 t2)
{// 推导类型来定义变量decltype(t1 * t2) ret;cout << typeid(ret).name() << endl;
}int main()
{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');return 0;
}

在这里插入图片描述

nullptr

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

4. 范围for

这个我们也很熟悉了,借助的是迭代器。只有有迭代器的容器才能使用。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> v{ 1,2,3,4,5,6,7,8,9 };for (auto e : v){cout << e << " ";}cout << endl;return 0;
}

在这里插入图片描述

5. STL中的一些变化

查文档戳这里

新容器

在这里插入图片描述
其中 unordered_setunordered_map 我们已经见过了,就是哈希表,array 则是静态数组,长度是已经固定的数组。forward_list 就是单链表。

新方法

基本每个容器中都增加了一些C++11的方法,但是其实很多都是用得比较少的。比如提供了cbegin和cend方法返回const迭代器等等,但是实际意义不大,因为begin和end也是可以返回const迭代器的,这些都是属于锦上添花的操作。还有其他新方法这里建议去看文档。

6. 右值引用和移动语句

左值引用和右值引用

传统的C++语法中就有引用的语法,而C++11中新增了的右值引用语法特性,所以从现在开始我们之前学习的引用就叫做 左值引用无论左值引用还是右值引用,都是给对象取别名。
那什么是左值,什么是右值?左值就是我们可以获取它的地址,并且它一般情况下是可以被赋值的就是左值。右值就是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值等等。
并不是在左边就是左值,右边就是右值。在引用时,左值和右值都在右边。
左值引用就是给左值的引用,给左值取别名。
右值引用就是对右值的引用,给右值取别名。

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;int main()
{// 以下的p、b、c、*p都是左值int* p = new int(0);int b = 1;const int c = 2;// 以下几个是对上面左值的左值引用int*& rp = p;int& rb = b;const int& rc = c;int& pvalue = *p;double x = 1.1, y = 2.2;// 以下几个都是常见的右值// 字面常量10;// 表达式x + y;// 返回值fmin(x, y);// 以下几个都是对右值的右值引用int&& rr1 = 10;double&& rr2 = x + y;double&& rr3 = fmin(x, y);return 0;
}

语法上:引用都是别名,不开空间,左值引用就是给左值取别名,右值引用就是给右值取别名。
底层上:引用都是指针实现的,左值引用存的是当前左值的地址。右值引用是把当前右值拷贝到栈上的一个临时空间,指向这个临时空间的地址。

左值引用只能引用左值,不能引用右值,但是const左值引用既可引用左值,也可引用右值。
右值引用只能右值,不能引用左值。但是右值引用可以move以后的左值。

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;int main()
{// 右值引用只能右值,不能引用左值。int&& r1 = 10;int a = 10;// 这里会报错int&& r2 = a;// 但这里会成功,右值引用可以引用move以后的左值int&& r3 = move(a);return 0;
}

未完待续

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 0729_驱动1 异步通知
  • RocketMQ Server Windows安装
  • 现在有什么赛道可以干到退休?
  • 【音视频之SDL2】Ubuntu编译配置SDL2环境
  • 如何实现无公网IP远程访问本地内网部署的Proxmox VE虚拟机平台
  • 莫斯科国际机场折腾“豪游”的我们
  • mac清理软件哪个好用免费 MacBook电脑清理软件推荐 怎么清理mac
  • 【Java算法专场】二分查找(上)
  • sortBy排序操作
  • 【JavaScript】01数组原型对象的最后一个元素、计数器
  • 【精通Redis】Redis命令详解
  • clangd配置
  • vue - devtools 安装
  • MacOS DockerDesktop配置文件daemon.json的位置
  • MakeReal3D v5.0 爆炸视图
  • ES6指北【2】—— 箭头函数
  • 4. 路由到控制器 - Laravel从零开始教程
  • CentOS 7 防火墙操作
  • co模块的前端实现
  • extjs4学习之配置
  • input的行数自动增减
  • JavaWeb(学习笔记二)
  • Java教程_软件开发基础
  • linux安装openssl、swoole等扩展的具体步骤
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • python 学习笔记 - Queue Pipes,进程间通讯
  • React Transition Group -- Transition 组件
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • Swift 中的尾递归和蹦床
  • 基于遗传算法的优化问题求解
  • 学习笔记TF060:图像语音结合,看图说话
  • 自定义函数
  • No resource identifier found for attribute,RxJava之zip操作符
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • #pragma 指令
  • #图像处理
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (Note)C++中的继承方式
  • (笔记)M1使用hombrew安装qemu
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (九十四)函数和二维数组
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十三)Maven插件解析运行机制
  • (五)activiti-modeler 编辑器初步优化
  • (一)appium-desktop定位元素原理
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)linux下的时间函数使用
  • (转)ObjectiveC 深浅拷贝学习
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .JPG图片,各种压缩率下的文件尺寸
  • .Net core 6.0 升8.0
  • .NET Core中的时区转换问题
  • .NET+WPF 桌面快速启动工具 GeekDesk