C++11

一、初始化

1、列表初始化{}(单一类型)

C++11_第1张图片

多参数的构造函数的隐式类型转换,之前只支持单参数的。

string ret = "xxxxxx"  (explicit可以阻止这种隐式转换)

C++11_第2张图片

2、initializer_list(类型转换)

底层为两个指针,一个指向第一个元素,另一个指向最后一个元素的后一个位置

C++11_第3张图片

C++11_第4张图片

initializer_list是类模板

C++11_第5张图片让vector支持lt构造。

        vector(initializer_list lt)
		{
			reserve(lt.size());
			for (auto e : lt)
			{
				push_back(e);
			}
		}

二、声明

1、decltype

C++11_第6张图片

2、auto

3、nullptr

void func(int* p)
{}
void func(int p)
{}
//const enum inline去替代宏
int main()
{
	int* p = NULL; // int* p = 0;
	func(NULL); // func(0);

	return 0;
}

三、final/override

CSDN

四、STL新增容器

1、array

C++11_第7张图片


int main()
{
	int a1[10];
	array a2;

	a1[15] = 1;  // 指针的解引用
	a2[15] = 1;  // operator[]函数调用,内部检查

	// 用这个也可以,显得array很鸡肋
	vector a3(10, 0);
}

2、forward_list

单链表

五、左值/右值

1、如何区分左值/右值

左值:是一个表示数据的表达式(如变量名或解引用的指针),我们 可以获取它的地址 ,一般可以对它赋 值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。
右值:也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边, 右值不能取地址 。右值引用就是对右值的引用,给右值取别名。

2、左值引用/右值引用

交叉使用

C++11_第8张图片

使用场景和价值

 左值引用的使用场景和价值是什么?
 使用场景:1、做参数  2、做返回值  价值->减少拷贝
 右值引用的使用场景和价值是什么?
 使用场景:某些情况下可以减少深拷贝

场景1:自定义类型中深拷贝的类,且必须传值返回的场景

C++11_第9张图片

右值引用如何减少深拷贝?

如何用右值引用进行优化?

C++11_第10张图片

C++11_第11张图片

一个深拷贝场景:

C++11_第12张图片

用右值引用接收 右值将亡值(自定义类型),内置类型为纯右值

s1:构造+拷贝构造+赋值 -->  构造+移动构造  2次深拷贝-->0次

s2:构造+拷贝构造+拷贝构造-->构造+移动构造(str是一个左值,为了优化为移动赋值,编译器内部将其识别为右值将亡值2次深拷贝-->0次(下图为s2的场景)

C++11_第13张图片

场景2:容器的插入接口,如果插入的对象是右值,可以利用移动构造将资源转移给数据结构中的对象,从而减少拷贝,提高效率。

push_back(val)  new Node(val)  _val(val)
都要提供一个&&右值引用的版本。

六、万能引用/完美转发

C++11_第14张图片

对于T&&接收后的t,无论是否折叠,即无论是左值引用&还是右值引用&&,其本身的属性是左值

当需要传递右值时,需要用forward(t)使其保持右值属性。

C++11_第15张图片

能传给swap中的左值引用,说明移动构造时s变量本身就为左值属性。

移动拷贝时需要swap完成资源转移,必须要修改,则右值引用本身为左值属性。

C++11_第16张图片

利用forward,逐层传递,保持右值属性。

你可能感兴趣的:(C++人生,c++,开发语言)