C++11中的特性(1)

✨前言✨

📘 博客主页:to Keep博客主页
🙆欢迎关注,👍点赞,📝留言评论
⏳首发时间:2024年5月28日
📨 博主码云地址:博主码云地址
📕参考书籍:《C++ Primer》《C++编程规范》
📢编程练习:牛客网+力扣网
**由于博主目前也是处于一个学习的状态,如有讲的不对的地方,请一定联系我予以改正!!!

1 列表化

在C++98的标准中,利用{}只可以对数组以及结构体进行初始化,而在C++11中就引入一切皆可列表化。C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

1.1 内置类型

int main()
{
	int a = 10;
	//内置类型利用初始化列表初始
	int b = { 10 };
	int c{ 10 };
}

1.2 自定义类型

class Student {
private:
	int _age;
	string _sex;
	string _classid;
public:
	Student(int age = 0,string sex = "男",string classid = "2024")
		:_age(age),
		_sex(sex),
		_classid(classid)
	{}
};
int main()
{
	//自定义类型支持列表化  构造+拷贝构造-->直接构造
	Student s1 = { 18,"男","1234" };
	Student s2{ 19,"女","1234" };
	Student* stu = new Student[4]{ { 19,"女","1234" },{ 18,"男","1234" } };
	return 0;
}

对于这一块的特性,还是用一下自定义类型利用{}进行初始化就可以了,内置类型还是和我们之前写法一样即可,这样看上去才不会那么奇怪!

2 initializer_list

在上面的示例中,我们可以发现对于Student这样的类型进行初始化的时候,我们只能固定的给相应的参数,但是对于库中vector或者是list却可以定义不同长度的对象!查看库中对应的构造函数,可以发现在C++11中引入了新的类型initializer_list。
在这里插入图片描述
通过查看该类型,可以发现这个类型就是专门接收传过来值的一个列表,然后利用这个列表对相应的类型进行初始化
在这里插入图片描述
我们也可以发现该类型中的成员函数有begin与end,也就是说有一个头指针和一个尾指针指向了这个列表,所以通过这个列表就可以接受到不同长度的值,从而就可以生成不同长度的对象!
在这里插入图片描述
所以在C++11中,对于许多容器来说,利用这个类型来初始化容器对象就很方便了!

3 右值引用

3.1左值与右值相关概念

首先我们先来搞清楚一个概念,什么是左值,什么是右值!对于左值与右值的概念如下所示:

左值:可以取到地址的就是左值,对于左值的引用就是左值引用,我们之前所将的引用一般就是指的左值引用,左值引用就是存储左值的地址!
右值:不能取到地址的就是右值,对于右值的引用就是右值引用,右值引用存储的是右值拷贝到栈上的临时空间,存储的就是这个临时空间的地址!常见的右值就是常量,表达式,函数返回值(传值返回也就是说出了函数作用域,就会销毁,需要拷贝的)

如下图所示:

int main()
{
	//以下a b *b c是左值
	int a = 3;
	int* b = new int(20);
	const int c = 10;

	//以下是对左值的引用
	int& ya = a;
	int* yb1 = b;
	const int& yc = c;
	int& yb2 = *b;
	return 0;

	double d1 = 1.1;
	double d2 = 2.2;
	//以下是右值
	10;
	x+y;
	fmax(x,y);
	
	//以下是对右值的引用
	int&& r1 = 10;
	double&& r2 = x+y;
	double&& r3 = fmax(x,y);
}

3.2 左值引用与右值引用的比较

对于左值引用我们可以发现

1️⃣左值引用不可以引用右值,只能引用左值
2️⃣const的左值引用既可以引用左值,又可以引用右值

在这里插入图片描述
对于右值引用而言

1️⃣右值引用不可以引用左值,只可以引用右值
2️⃣右值引用可以引用经过move之后的左值

在这里插入图片描述
注意:move不能想怎么样用就怎么样的用,必须根据下面的代码是否有可能会用到当前的左值,如果用不到,那利用move函数将左值变为右值,然后利用移动语义对资源进行移动!

3.3 相关的应用场景

引用的目的就是为了减少拷贝,提高性能,而左值引用就是我们之前一直在使用的引用,传值传参的引用(常见的就是我们之前所学过的拷贝构造函数)以及函数返回值(出了函数作用域,该引用的对象还存在)的引用!同理,右值引用的目的也是为了减少拷贝,它存在的意义就是解决左值引用所解决不了的问题!也就是说右值引用主要作用于哪些出了作用域就已经销毁了的对象,以及匿名对象!目的就是为了减少拷贝,将右值(有些文章中也称为将亡值)中的资源给转移走!如何把资源转移呢?这就要简单的介绍以下移动构造以及移动赋值

移动构造:移动构造本质是将参数右值的资源窃取过来,占位已有,那么就不用做深拷贝了,所以它叫做移动构造,就是窃取别人的资源来构造自己。(移动赋值的原理也是一样的,都是通过掠夺将亡值的资源来构造自己)

如下图所示就是移动构造与移动赋值
在这里插入图片描述
对上述有了一个基本了解之后,我们以下面这个示例为例,从而进一步的了解编译器的优化规则:
在这里插入图片描述

在这里插入图片描述
在上图中的C++11优化中,如果没有移动构造,那么还是会继续调用拷贝构造的!因为拷贝构造中是const的左值引用,这样既可以引用左值又可以引用右值!

资源移动的原理:在一开始我们就知道了,右值是不允许被修改的,但是右值一旦经过引用(也就是右值引用),属性就会发生了变化,就变成左值的属性。那么也就可以进行改变,从而实现资源的转移!

3.4 万能引用

万能引用就是如下所示,就是根据T&&可以接收左值引用,也可以接收右值引用,如果是左值引用,那么模版就会推演成T&,如果是右值引用,模版就会推演成T&&(推演会将T转化成具体的类型,这里为了表述,就直接用了T)
在这里插入图片描述
我们可以发现,为什么全是左值引用呢?那是因为右值引用是具有左值属性,所以就都去调用对应的左值引用的函数了!为了解决这个问题,就提出了完美转发的解决办法!

完美转发:就是利用std::forward(t)在传参的过程中保持了t的原生类型属性

所以对代码的改进如下所示:
在这里插入图片描述

4 新的类功能

在之前的学习过程中,我们知道类和对象中是有6个默认的构造函数,在C++11中又添加了2个默认的构造,移动构造与移动赋值函数!

1️⃣如果你没有自己实现移动构造函数
2️⃣没有自己实现析构函数 、拷贝构造、拷贝赋值重载中的任意一个。

满足了上述两个条件,那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造。如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。也就是说一个类只要他需要深拷贝,就必定需要自己实现以上三个函数,也必定需要我们自己去实现资源的移动!移动赋值的原理就和移动构造的原理是一样的(只不过要是没有移动赋值,那么就会调用拷贝赋值)!
在C++11中,还提出了利用default关键字来强制生成默认函数,利用delete关键字强制的禁止生成默认函数!这个在某些特定的场景下还是有用的(比如我们不允许某个类可以进行拷贝)!
如下图所示:

class Date {
private:
	int _year;
	int _month;
	int _day;

public:
	Date(Date& date) = delete;//禁止生成默认的拷贝构造

	Date() = default; //强制生成默认的构造函数
};

5 总结

在C++11中还引入了以下STL容器,其中unordered_map就是相当于Java中的hashmap,但是对于添加的array以及forward_list这两个容器就很鸡肋了!感觉作用不是特别大!
对于C++11中还引入了array,
对于本文中C++11最重要的特性就是引入右值引用,利用移动语义,移动右值中的资源来进行构造,从而减少拷贝,提高程序的性能!

  • 33
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

to Keep

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值