0
点赞
收藏
分享

微信扫一扫

C++11 新特性

C++11


目录



列表初始化


class Person {
public:
	Person(const string& name, int age) :_name(name), _age(age) {}
private:
	string _name;
	int _age;
};

int main()
{
	int i = { 1 };
	vector<int> v = { 1,2,3 };
	vector<int> v2{ 1,2,3 };
	vector<int>{1, 2, 3};
	//比较实用还是这种方式
	Person* p_Arr = new Person[2]{ {"张三",31},{"李四",22} };
}

在这里插入图片描述

	initializer_list<int> l1{ 1,2,3 };
	initializer_list<string> l2{ "1","2","3" };

如果需要自定义类型支持花括号初始化,需要支持这样的构造函数。

template <class T>
class my_vector
{
	my_vector(initializer_list<T> li) {
		for (const T& x : li) {
			this->push_back(x);
		}
	}
	//...
	//...
	//...
	//...
private:

};
int main()
{
	my_vector<int> v = { 1,2,3,4 };


范围for

范围for本质还是由迭代器实现。需要注意,取出的元素是值传递,如不需要修改最好加上const &

int main()
{
	vector<string> v = { "1","6" ,"54" ,"3" };
	for (const string& i : v) {
		cout << i;
	}
}



STL中的新容器

在这里插入图片描述


array

一个存在栈上的静态数组,除了内部对下标访问做了检查,防止越界好像就没什么用。。



forward_list

底层是单链表,比list 少了尾插和尾插。唯一的优点就是少了一个存储前一个节点的指针节省了几字节。。



unordered_map/set

非常好用的容器,底层为hash表,但为什么到C++11 才支持。。



右值引用 移动语义


C++11 之前就有引用,应该称为左值引用,而C++11中新增了的右值引用语法特性,无论左值引用还是右值引用,都是给对象取别名。



什么是左值、右值


这些都是左值

	int i = 1;
	const int i2 = 1;
	int* pa = new int[2]{ 1,2 };

左值的共同点:它们都可以被取地址,也基本可以修改(除了被const修饰)


右值可以是一个表达式,如:字面常量、表达式返回值,传值返回函数的返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。右值引用就是对右值的引用,给右值取别名。

这些都是右值

string func2()
{
	string s1 = "12";
	return s1;
}

int main()
{
	int x, y;
	x + y;
	10;
	1 + 2;
	func2();
}

右值的共同点:它们都不能出现在赋值运算符的右边和被取地址,也不能被修改

	int&& rr1 = 123;
	rr1 = 2;	//此时rr1已经是一个左值了,可以被修改


左值引用


左值引用小结:

左值引用只能引用左值,不能引用右值。

但是const左值引用既可引用左值,也可引用右值,例如:

const int i = 1;

在没有右值引用之前这种场景非常常用:
当模板类型为int、double 这种类型,就相当引用了右值

template <class T>
class my_vector
{
	void push_back(const T& x) {
		//....
	}
}

左值引用的短板

当函数返回对象是一个局部变量,出了函数作用域就不存在了,就不能使用左值引用返回,只能传值返回。例如: 标准库中的to_sting函数

在这里插入图片描述

to_string 只能使用传值返回,传值返回会导致至少1次拷贝构造(如果是一些旧一点的编译器可能是两次拷贝构造)。



右值引用


右值引用解决了上面左值引用的缺点,本质也是为了减少拷贝。


只有拷贝构造情况下,依旧会产生一次深拷贝。
在这里插入图片描述

但如果提供了移动构造,就不会产生深拷贝,同时有拷贝构造和移动构造的情况下,优先选择移动构造。
在这里插入图片描述

func函数中的临时对象出了作用域就即将销毁了,有些地方叫将亡值,使用移动构造相当于废物利用,直接将临时对象中的数据交换到新对象上来,减少了深拷贝,提高效率,这是右值引用的一个使用场景。

举报

相关推荐

C++11新特性

C++11新特性介绍

c++11容器新特性

c++11新特性-下

C++11新特性之并发

0 条评论